2009-12-17 4 views
16

Comment allouer de la mémoire alignée sur une limite spécifique dans C (par exemple, limite de ligne de cache)? Je cherche une implémentation de type malloc/free qui soit idéalement aussi portable que possible --- au moins entre les architectures 32 et 64 bits.Comment allouer et libérer de la mémoire alignée dans C

Modifier pour ajouter: En d'autres termes, je cherche quelque chose qui se comporterait comme (maintenant obsolète?) memalign fonction, qui peut être libérée en utilisant gratuitement.

+0

Avez-vous vérifié ces deux réponses sur SO: http://stackoverflow.com/questions/227897/solve-the-memory-alignment-in-c-interview-question-that-stumped-me/227900#227900 http://stackoverflow.com/questions/1855896/memory-alignment-on-modern-processors? –

+0

Pas tout à fait ce que je cherche. Je voudrais quelque chose qui fonctionne plus comme malloc, retourne une valeur qui est le pointeur aligné, alors avoir une autre fonction similaire à free, c'est appelé sur ce pointeur. L'application d'une solution telle que celles que vous avez pointées nécessite soit de passer deux valeurs, soit de recalculer l'alignement chaque fois que cela est nécessaire. Je cherche quelque chose de similaire à memalign. Merci d'avoir signalé ces réponses. – fuad

+1

Il y a 'posix_memalign()' sur les machines appropriées - a une interface différente de 'memalign()'. –

Répondre

24

Voici une solution, qui encapsule l'appel à malloc, alloue un plus grand tampon à des fins d'alignement, et stocke l'adresse allouée originale juste avant le tampon aligné pour un appel ultérieur à libérer.

// 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

une distribution à 'uintptr_t' –

+0

@Jermoe En particulier, le code ne fonctionne pas sur Windows 64 bits – user877329

+0

@Jerome - Pour une raison particulière, vous dites' malloc (taille + ALIGN + sizeof (void *)) 'et pas' malloc (taille + ALIGN-1 + sizeof (void *)) '? Si vous vous alignez sur une limite * n * -byte, vous n'avez besoin que d'au plus * n * - 1 octet supplémentaire. –

3

Quel compilateur utilisez-vous? Si vous êtes sur MSVC, vous pouvez essayer _aligned_malloc() et _aligned_free().

+0

Compilateur de Sun pour Solaris/SPARC et gcc pour Linux/x86 – fuad

+1

Sun prend en charge memalign(): http://docs.sun.com/app/docs/doc/816-5168/malloc-3c?a=view Je ne vois aucune indication que memalign() est obsolète dans le Avec les nouvelles normes, vous devriez envisager de remplacer la distribution par «long» avec: http://cvs.savannah.gnu.org/viewvc/libc/malloc/malloc.h?revision=1.32&root=libc&view=markup – mrkj

7

Utilisez 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 est un remplacement standard pour memalign qui, comme vous le mentionnez est obsolète.

Questions connexes