utiliza usar memoria dinamica como c memory-management intel dynamic-memory-allocation

memoria - ¿Por qué usar_mm_malloc?(a diferencia de_aligned_malloc, alligned_alloc o posix_memalign)



malloc sizeof (3)

Hay algunas opciones para adquirir un bloque de memoria alineado, pero son muy similares y el problema se reduce principalmente al idioma estándar y las plataformas a las que te diriges.

C11

void * aligned_alloc (size_t alignment, size_t size)

POSIX

int posix_memalign (void **memptr, size_t alignment, size_t size)

Windows

void * _aligned_malloc(size_t size, size_t alignment);

Y, por supuesto, también es siempre una opción para alinear a mano.

Intel ofrece otra opción.

Intel

void* _mm_malloc (int size, int align) void _mm_free (void *p)

Según el código fuente publicado por Intel, este parece ser el método de asignación de memoria alineada que prefieren sus ingenieros, pero no puedo encontrar ninguna documentación que la compare con otros métodos. Lo más cercano que encontré simplemente reconoce que existen otras rutinas de asignación de memoria alineadas.

https://software.intel.com/en-us/articles/memory-management-for-optimal-performance-on-intel-xeon-phi-coprocessor-alignment-and

Para asignar dinámicamente una parte de la memoria alineada, use posix_memalign, que es compatible con GCC y con el compilador de Intel. La ventaja de usarlo es que no tiene que cambiar la API de eliminación de memoria. Puedes usar free () como siempre lo haces. Pero presta atención al perfil de parámetros:

int posix_memalign (void ** memptr, size_t align, size_t size);

El compilador de Intel también proporciona otro conjunto de API de asignación de memoria. Los programadores de C / C ++ pueden usar _mm_malloc y _mm_free para asignar y liberar bloques alineados de memoria. Por ejemplo, la siguiente declaración solicita un bloque de memoria alineado de 64 bytes para 8 elementos de punto flotante.

farray = (float *) __ mm_malloc (8 * sizeof (float), 64);

La memoria asignada mediante _mm_malloc debe liberarse utilizando _mm_free. Llamar gratis en la memoria asignada con _mm_malloc o llamar a _mm_free en la memoria asignada con malloc resultará en un comportamiento impredecible.

Las diferencias claras desde la perspectiva del usuario es que _mm_malloc requiere _mm_malloc directo de la CPU y del compilador, y la memoria asignada con _mm_malloc debe liberarse con _mm_free . Dados estos inconvenientes, ¿cuál es la razón para usar _mm_malloc? ¿Puede tener una ligera ventaja de rendimiento? Accidente histórico?


Es posible tomar un compilador de C existente que actualmente no utiliza los identificadores _mm_alloc y _mm_free y definir funciones con aquellos nombres que se comportarán según sea necesario. Esto se puede hacer ya sea teniendo la función _mm_alloc como envoltorio en malloc() que solicita una asignación ligeramente más grande y construye un puntero a la primera dirección adecuadamente alineada dentro de ella, que es al menos un byte desde el principio, y almacena el número de bytes omitidos inmediatamente antes de esa dirección, o haciendo que _mm_malloc solicite grandes porciones de memoria de malloc() y luego los distribuya por partes. En cualquier caso, los punteros devueltos por _mm_malloc() no serían punteros con los que free() generalmente sabría cómo hacer nada; llamar a _mm_free usaría el byte inmediatamente anterior a la asignación como una ayuda para encontrar el inicio real de la asignación recibida de malloc , y luego pasar que hacer free .

Sin embargo, si se permite que una función de asignación alineada utilice las funciones internas de malloc y free funciones free , puede eliminar la necesidad de la capa adicional de ajuste. Es posible escribir las _mm_alloc() / _mm_free() que envuelven malloc / free sin saber nada sobre sus _mm_alloc() internos, pero requiere que _mm_alloc() mantenga la información de contabilidad que es independiente de la utilizada por malloc / free .

Si el autor de una función de asignación alineada sabe cómo se implementan malloc y free , a menudo será posible coordinar el diseño de todas las funciones de asignación / libre para que free pueda distinguir todo tipo de asignaciones y manejarlas adecuadamente. Sin embargo, ninguna implementación de asignación alineada única sería utilizable en todas free implementaciones de malloc / free .

Yo sugeriría que la forma más portátil de escribir código probablemente sería seleccionar un par de símbolos que no se usen en ningún otro lugar para sus propias funciones de asignación y gratuitas, de modo que pueda decir, por ejemplo:

#define a_alloc(align,sz) _mm_alloc((align),(sz)) #define a_free(ptr) _mm_free((ptr))

en compiladores que soportan eso, o

static inline void *aa_alloc(int align, int size) { void *ret=0; posix_memalign(&ret, align, size); // Guessing here return ret; } #define a_alloc(align,sz) aa_alloc((align),(sz)) #define a_free(ptr) free((ptr))

en sistemas Posix, etc. Para cada sistema debería ser posible definir macros o funciones que produzcan el comportamiento necesario [Creo que probablemente sea mejor usar macros de manera consistente que a veces usar macros y, a veces, funciones, para permitir #if defined macroname para probar si las cosas están definidas todavía].


Los compiladores de Intel son compatibles con los sistemas operativos POSIX (Linux) y no POSIX (Windows), por lo que no pueden confiar en la función POSIX ni en la función de Windows. Por lo tanto, se eligió una solución específica para el compilador pero para el sistema operativo.

C11 es una gran solución, pero Microsoft aún no admite C99 todavía, así que quién sabe si alguna vez será compatible con C11.

Actualización: A diferencia de las funciones de asignación de C11 / POSIX / Windows, los intrínsecos ICC incluyen una función de desasignación. Esto permite que esta API utilice un gestor de almacenamiento dinámico separado del predeterminado. No sé si / cuándo realmente lo hace, pero puede ser útil para apoyar este modelo.

Descargo de responsabilidad: trabajo para Intel, pero no tengo un conocimiento especial de estas decisiones, lo cual sucedió mucho antes de unirme a la empresa.


Parece que _mm_malloc se creó antes de que existiera una función alineada_alloc estándar, y la necesidad de usar _mm_free es una peculiaridad de la implementación.

Mi conjetura es que, a diferencia de cuando se usa posix_memalign, no es necesario que se asigne en exceso para garantizar la alineación, sino que utiliza un asignador separado que reconoce la alineación. Esto ahorrará memoria al asignar tipos con alineación diferente a la alineación predeterminada (normalmente 8 o 16 bytes).