c++ - theft - ¿Cómo los juegos como GTA IV no fragmentan el montón?
gta 4 android (6)
Crear y destruir muchos objetos realmente rápidamente no necesariamente significa fragmentación de pilas. A menudo, si los objetos son del mismo tamaño, entonces el espacio liberado por uno puede asignarse para el siguiente.
A menudo, incluso como una optimización, es posible que un programa no libere y elimine la memoria de los objetos, sino que mantenga los antiguos en un grupo y simplemente tome uno y sobrescriba el contenido para crear un objeto "nuevo".
Me interesa el tipo de gestión de memoria que un juego como GTA IV podría usar, ya que necesita crear y eliminar muchos objetos muy rápidamente. ¿Cómo evitar la fragmentación del montón y otras cosas. Si alguien pudiera apuntarme en la dirección correcta, realmente lo apreciaría.
Creo que debido a que sus objetos son en su mayoría del mismo tamaño, pueden usar algún administrador de memoria interno que en realidad no libera memoria, pero lo marca como disponible y la próxima vez que se asigna un trozo de ~ tamaño se lo devuelve.
Muchos juegos usan algunos de los asignadores de memoria mencionados aquí. dlmalloc es uno que hemos utilizado con gran éxito (lo hemos vinculado a Lua). Puedes obtener información sobre dlmalloc here .
Sin embargo, otra cosa que mencionaría es que no todos los juegos tienen que usar la asignación de memoria dinámica. Hemos empleado mempools y el uso de regiones de memoria estática para la mayoría de nuestros datos de juego. Solo los sistemas que requieren una asignación dinámica lo hacen (Lua y algunas bibliotecas de terceros). Todo lo demás que hacemos proviene de buffers estáticos. Tampoco utilizamos STL en el código de juego, lo que ayuda a limitar el "daño" de la fragmentación de la memoria.
Si bien este documento no se refiere específicamente a los juegos, proporciona un buen resumen del tipo de asignadores de memoria personalizados que las personas emplean a menudo en las aplicaciones de C y C ++ en un intento por mejorar el rendimiento (y es un poco de advertencia).
Reconsiderando la asignación de memoria personalizada , Berger, Zorn & McKinley, OOPSLA 2002
Los programadores que esperan lograr mejoras de rendimiento a menudo usan asignadores de memoria personalizados. Este estudio en profundidad examina ocho aplicaciones que usan asignadores personalizados. Sorprendentemente, para seis de estas aplicaciones, un asignador de propósito general de última generación (el asignador de Lea) se desempeña tan bien o mejor que los asignadores personalizados. Las dos excepciones utilizan regiones, que ofrecen un mayor rendimiento (mejoras de hasta un 44%). Las regiones también reducen la carga del programador y eliminan una fuente de fugas de memoria. Sin embargo, mostramos que la incapacidad de los programadores para liberar objetos individuales dentro de las regiones puede llevar a un aumento sustancial en el consumo de memoria. Peor aún, esta limitación impide el uso de regiones para los lenguajes de programación comunes, lo que reduce su utilidad. Presentamos una generalización de asignadores de propósito general y basados en la región que llamamos cosechas. Las cosechas son una combinación de regiones y montones, que proporcionan una gama completa de semánticas de regiones con la adición de la eliminación de objetos individuales. Demostramos que nuestra implementación de cosechas proporciona un alto rendimiento, superando a otros asignadores con una semántica similar a la región. Luego usamos un estudio de caso para demostrar las ventajas de espacio y los beneficios de ingeniería de software de las cosechas en la práctica. Nuestros resultados indican que los programadores que necesitan regiones rápidas deberían usar cosechas, y que la mayoría de los programadores que consideran asignadores personalizados deberían usar el asignador de Lea.
Usan cosas como la agrupación de memoria , los asignadores especializados y las clases especializadas de contenedor.
- El asignador de memoria Hoard para programas multihilo.
- La versión de EA de la STL . Contiene repartidores, contenedores,
Hay dos implementaciones malloc
muy buenas para implementaciones de subprocesos múltiples:
-
tcmalloc
: de Google -
jemalloc
: utilizado por Apache (por ejemplo)
Aquí está el artículo de Facebook sobre la mejora de jemalloc . Es aproximadamente 5 veces más rápido que el asignador de memoria de Hoard en la respuesta principal actual :)