Comparación de rendimiento del mecanismo de asignación de memoria C++ (tcmalloc vs. jemalloc)


Tengo una aplicación que asigna mucha memoria y estoy considerando usar un mecanismo de asignación de memoria mejor que malloc.

Mis opciones principales son: jemalloc y tcmalloc. ¿Hay algún beneficio en el uso de cualquiera de ellos sobre el otro?

Hay una buena comparación entre algunos mecanismos (incluido el mecanismo propietario del autor lock lockless) en http://locklessinc.com/benchmarks.shtml y menciona algunos pros y contras de cada uno de ellos.

Dado que ambos mecanismos estén activos y mejorando constantemente. ¿Alguien tiene alguna idea o experiencia sobre el desempeño relativo de estos dos?

Author: Shayan Pooya, 2011-10-21

6 answers

Si no recuerdo mal, la principal diferencia era con los proyectos multihilo.

Ambas bibliotecas intentan adquirir memoria de contención haciendo que los hilos escojan la memoria de diferentes cachés, pero tienen diferentes estrategias:

  • jemalloc (utilizado por Facebook) mantiene una caché por hilo
  • tcmalloc (de Google) mantiene un conjunto de cachés, y los hilos desarrollan una afinidad "natural" para un caché, pero pueden cambiar

Esto llevó, una vez más si recuerdo correctamente, a una diferencia importante en términos de gestión de hilos.

  • jemalloc es más rápido si los subprocesos son estáticos, por ejemplo, usando pools
  • tcmalloc es más rápido cuando se crean/destruyen hilos

También existe el problema de que desde jemalloc girar nuevas cachés para acomodar nuevos id de subprocesos, tener un pico repentino de subprocesos te dejará con (en su mayoría) cachés vacíos en la fase de calma posterior.

Como resultado, recomendaría tcmalloc en el caso general, y reserve jemalloc para usos muy específicos (baja variación en el número de hilos durante la vida útil de la aplicación).

 34
Author: Matthieu M.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-10 06:52:35

Recientemente he considerado tcmalloc para un proyecto en el trabajo. Esto es lo que observé:

  • Rendimiento mejorado en gran medida para el uso intensivo de malloc en un entorno multihilo. Lo utilicé con una herramienta en el trabajo y el rendimiento mejoró casi dos veces. La razón es que en esta herramienta había unos pocos hilos que realizaban asignaciones de objetos pequeños en un bucle crítico. Usando glibc, el rendimiento sufre debido, creo, a las disputas de bloqueo entre malloc / llamadas gratuitas diferentes hilos.

  • Desafortunadamente, tcmalloc aumenta la huella de memoria. La herramienta que mencioné anteriormente consumiría dos o tres veces más memoria (medida por el tamaño máximo del conjunto residente). El aumento de la huella no es una opción para nosotros, ya que en realidad estamos buscando formas de reducir la huella de memoria.

Al final he decidido no usar tcmalloc y en su lugar optimizar el código de la aplicación directamente: esto significa eliminar las asignaciones de la bucles para evitar las contenciones malloc / free lock. (Para los curiosos, usar una forma de compresión en lugar de usar grupos de memoria.)

La lección para usted sería que debe medir cuidadosamente su aplicación con cargas de trabajo típicas. Si puede permitirse el uso de memoria adicional, tcmalloc podría ser ideal para usted. Si no, tcmalloc sigue siendo útil para ver lo que ganarías al evitar las llamadas frecuentes a la asignación de memoria entre subprocesos.

 10
Author: Alexey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-04 11:21:51

Tenga en cuenta que de acuerdo con la página de inicio 'nedmalloc', los asignadores del sistema operativo moderno son en realidad bastante rápidos ahora:

"Windows 7, Linux 3.x, FreeBSD 8, Mac OS X 10.6 todos contienen asignadores de última generación y es probable que ningún asignador de terceros mejore significativamente en los resultados del mundo real "

Http://www.nedprod.com/programs/portable/nedmalloc

Así que usted podría ser capaz de salirse con la suya simplemente recomendando a sus usuarios actualizar o algo por el estilo:)

 4
Author: rogerdpack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-13 22:56:05

También podría considerar el uso de Boehm conservative garbage collector. Básicamente, usted reemplaza cada malloc en su código fuente con GC_malloc (etc...), y no te molestes en llamar free. El GC de Boehm no asigna memoria más rápidamente que malloc (es casi lo mismo, o puede ser un 30% más lento), pero tiene la ventaja de lidiar con zonas de memoria inútiles automáticamente, lo que podría mejorar su programa (y ciertamente facilita la codificación, ya que no le importa más lo gratuito). Y el GC de Boehm también se puede usar como asignador de C++.

Si realmente cree que malloc es demasiado lento (pero debería hacer benchmark; la mayoría de malloc-s toman menos de microsegundos), y si comprende completamente el comportamiento de asignación de su programa, podría reemplazar algunos malloc-s con su asignador especial (que podría, por ejemplo, obtener memoria del núcleo en grandes trozos usando mmap y administrar la memoria por sí mismo). Pero creo que hacer eso es un dolor. En C++ tienes el asignador concepto y std::allocator_traits, con la mayoría de los contenedores estándar plantillas que aceptan dicho asignador (véase también std::allocator), por ejemplo, el segundo argumento de plantilla opcional para std::vector, etc...

Como otros sugirieron, si cree que malloc es un cuello de botella, podría asignar datos en trozos (o utilizando arenas), o simplemente en una matriz.

A veces, implementar un recolector de basura de copia especializada (para algunos de sus datos) podría ayudar. Considerar quizás MPS.

Pero no olvide que la optimización prematura es mala y por favor compare y perfile su aplicación para entender exactamente dónde se pierde el tiempo.

 2
Author: Basile Starynkevitch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-05 05:45:51
 1
Author: SunfiShie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-21 17:06:04

Tu post no menciona el threading, pero antes de considerar mezclar métodos de asignación de C y C++, investigaría el concepto de memory pool.BOOST tiene una buena.

 1
Author: Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-21 17:13:38