5

Actualmente estoy investigando la implementación de malloc() en Windows. Pero en mi investigación he topado con cosas que me dejó perplejo:Preguntas sobre la asignación de memoria de Windows

En primer lugar, sé que a nivel de API, Windows utiliza en su mayoría los HeapAlloc() y VirtualAlloc() llamadas para asignar memoria. De acuerdo con here, la implementación de Microsoft de malloc() (la que está incluida en el CRT - el tiempo de ejecución de C) básicamente llama a HeapAlloc() para bloques> 480 bytes y gestiona un área especial asignada con VirtualAlloc() para pequeñas asignaciones, a fin de evitar la fragmentación.

Bueno, eso está bien y está bien. Pero luego hay otra implementación de malloc(), por ejemplo nedmalloc, que dice ser hasta 125% más rápida que la de malloc de Microsoft.

Todo esto me hace pensar algunas cosas:

  1. Por qué no podemos simplemente llamar HeapAlloc() para los pequeños bloques? ¿Tiene un rendimiento bajo en lo que respecta a la fragmentación (por ejemplo, al hacer "primer ajuste" en lugar de "mejor ajuste")?

    • En realidad, ¿hay alguna manera de saber qué es lo que está pasando por debajo de las diversas llamadas de asignación de API? Eso sería bastante útil.
  2. Lo que hace nedmalloc mucho más rápido que Microsoft de malloc?

  3. De lo anterior, me dio la impresión de que HeapAlloc()/VirtualAlloc() son tan lento que es mucho más rápido para malloc() llamarlos sólo una vez en un tiempo y después de administrar la memoria asignada en sí. Es esa suposición verdadera? ¿O simplemente se necesita el "contenedor" malloc() debido a la fragmentación? Uno pensaría que las llamadas al sistema de este tipo serían rápidas, o al menos que se habrían puesto algunas ideas para hacerlas más eficientes.

    • Si bien es cierto, ¿por qué es así?
  4. En promedio, ¿cuántos (un orden de magnitud) de memoria lee/escritura son realizadas por un típico malloc llamada (probablemente una función del número de segmentos ya asignados)? Intuitivamente diría que está en las decenas para un programa promedio, ¿estoy en lo cierto?

+0

Por otro lado, leer en "dlmalloc" es muy informativo sobre las estrategias de malloc – Will

Respuesta

5
  1. Calling HeapAlloc no suena multiplataforma. MS es libre de cambiar su implementación cuando lo desee; Aconseja mantenerte alejado. :)
  2. Probablemente está utilizando las agrupaciones de memoria de manera más efectiva, al igual que la biblioteca Loki hace con su "pequeño objeto asignador"
  3. Las asignaciones de montón, que son de propósito general por naturaleza, siempre son lentas mediante cualquier implementación. Cuanto más "especializado" sea el asignador, más rápido será. Esto nos devuelve al punto n. ° 2, que trata con los grupos de memoria (y los tamaños de asignación utilizados que son específicos de su aplicación).
  4. No lo sé.
+0

Microsoft también puede cambiar las cosas para mejorar todo. Ver la transición al montón de baja fragmentación. – MSN

+0

1. Tampoco esperaba que lo fuera, ya que estoy intentando un objetivo de implementación malloc en Windows. Pero la pregunta sigue siendo: ¿es ineficaz, fragmentada? 2. ¿Con esto quiere decir que administra punteros para liberar espacio de forma más eficiente, de modo que la asignación del bloque apropiado en la memoria es más rápida? ¿Sabes dónde puedo leer sobre pools de memoria? Según lo sugerido por el usuario Antes, comencé en dlmalloc (lo revisé previamente pero sonaba orientado a unix, describiendo su funcionalidad de Windows como emular las llamadas de Unix). – Norswap

1

De lo anterior, me dio la impresión de que HeapAlloc()/VirtualAlloc() son tan lento que es mucho más rápido para malloc() para llamar sólo una vez en un tiempo y después de administrar el asignado memoria en sí Es esa suposición verdadera?

Las llamadas al sistema de nivel de sistema operativo están diseñadas y optimizadas para administrar todo el espacio de memoria de los procesos. Usarlos para asignar 4 bytes para un número entero es de hecho subóptimo: se obtiene un mejor rendimiento general y uso de memoria mediante la administración de pequeñas asignaciones en el código de la biblioteca y permitiendo que el sistema operativo optimice para asignaciones más grandes. Al menos hasta donde yo lo entiendo