2009-12-17 20 views
16

¿Cómo se asigna la memoria que está alineada con un límite específico en C (por ejemplo, el límite de la línea de caché)? Estoy buscando una implementación malloc/free que idealmente sea lo más portátil posible, al menos entre arquitecturas de 32 y 64 bits.Cómo asignar y memoria alineada libre en C

Editar para agregar: En otras palabras, estoy buscando algo que se comportara como (¿la ahora obsoleta?) memalign función, que se puede liberar con el uso gratuito.

+0

¿Ha comprobado estas dos respuestas en SO: http://stackoverflow.com/questions/227897/solve-the-memory-alignment-in-c-interview-question-that-stumped-me/227900#227900 y http://stackoverflow.com/questions/1855896/memory-alignment-on-modern-processors? –

+0

No es exactamente lo que estoy buscando. Me gustaría algo que funciona más como malloc, devuelve un valor que es el puntero alineado, y luego tiene otra función similar a libre, que se llama en ese puntero. La aplicación de una solución como las que usted señala requiere pasar dos valores o volver a calcular la alineación cuando sea necesario. Estoy buscando algo similar a memalign. Gracias por señalar esas respuestas. – fuad

+1

Hay 'posix_memalign()' en las máquinas apropiadas - tiene una interfaz diferente de 'memalign()'. –

Respuesta

24

Aquí hay una solución, que encapsula la llamada a malloc, asigna un búfer más grande para fines de alineación, y almacena la dirección asignada original justo antes del búfer alineado para una llamada posterior a libre.

// cache line 
#define ALIGN 64 

void *aligned_malloc(int size) { 
    void *mem = malloc(size+ALIGN+sizeof(void*)); 
    void **ptr = (void**)((uintptr_t)(mem+ALIGN+sizeof(void*)) & ~(ALIGN-1)); 
    ptr[-1] = mem; 
    return ptr; 
} 

void aligned_free(void *ptr) { 
    free(((void**)ptr)[-1]); 
} 
+2

con los nuevos estándares, debería considerar reemplazar el elenco a 'long' con un yeso a 'uintptr_t' –

+0

@Jermoe En particular, el código no funciona en Windows de 64 bits – user877329

+0

@Jerome - Cualquier razón particular que diga' malloc (tamaño + ALIGN + sizeof (void *)) 'y no' malloc (tamaño + ALIGN-1 + sizeof (void *)) '? Si se está alineando con un límite * n * -byte, solo necesitará como mucho * n * - 1 byte adicional. –

3

¿Qué compilador estás usando? Si está en MSVC, puede probar _aligned_malloc() y _aligned_free().

+0

Compilador de Sun para Solaris/SPARC y gcc para Linux/x86 – fuad

+1

Parece Sun admite memalign(): http://docs.sun.com/app/docs/doc/816-5168/malloc-3c?a=view No veo ninguna indicación de que memalign() esté en desuso en el glibc actual: http://cvs.savannah.gnu.org/viewvc/libc/malloc/malloc.h?revision=1.32&root=libc&view=markup – mrkj

7

Uso posix_memalign/free.

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

void* ptr; 
int rc = posix_memalign(&ptr, alignment, size); 
... 
free(ptr) 

posix_memalign es un reemplazo estándar para memalign que, como usted menciona es obsoleto.

Cuestiones relacionadas