2009-12-17 14 views
16

Come si alloca la memoria allineata a un limite specifico in C (ad esempio, limite della linea cache)? Sto cercando un'implementazione malloc/free che idealmente sarebbe il più portabile possibile - almeno tra le architetture a 32 e 64 bit.Come allocare e liberare memoria allineata in C

Modifica da aggiungere: In altre parole, sto cercando qualcosa che si comporti come (la ormai obsoleta?) Funzione memalign, che può essere liberata utilizzando gratuitamente.

+0

Avete controllato queste due risposte su SO: http://stackoverflow.com/questions/227897/solve-the-memory-alignment-in-c-interview-question-that-stumped-me/227900#227900 e http://stackoverflow.com/questions/1855896/memory-alignment-on-modern-processors? –

+0

Non proprio quello che sto cercando. Vorrei qualcosa che funziona più come malloc, restituisce un valore che è il puntatore allineato, quindi ha un'altra funzione simile a free, che viene chiamata su quel puntatore. L'applicazione di una soluzione come quella che hai indicato richiede il passaggio di due valori o il ricalcolo dell'allineamento ogni volta che è necessario. Sto cercando qualcosa di simile al memalign. Grazie per aver indicato quelle risposte. – fuad

+1

C'è 'posix_memalign()' su macchine appropriate - ha un'interfaccia diversa da 'memalign()'. –

risposta

24

Ecco una soluzione che incapsula la chiamata a malloc, alloca un buffer più grande per scopo di allineamento e memorizza l'indirizzo allocato originale appena prima del buffer allineato per una chiamata successiva a free.

// 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 i nuovi standard, dovresti prendere in considerazione la possibilità di sostituire il cast in 'long' con un cast per 'uintptr_t' –

+0

@Jermoe In particolare, il codice non funziona su Windows a 64 bit – user877329

+0

@Jerome - Qualsiasi motivo particolare per cui si dice' malloc (dimensione + ALIGN + sizeof (void *)) 'e non' malloc (size + ALIGN-1 + sizeof (void *)) '? Se stai allineando a un limite * n * -byte, allora hai sempre bisogno solo di * n * - 1 byte in più. –

3

Che compilatore stai utilizzando? Se sei su MSVC, puoi provare _aligned_malloc() e _aligned_free().

+0

Compilatore di Sun per Solaris/SPARC e gcc per Linux/x86 – fuad

+1

Assomiglia Sun supporta memalign(): http://docs.sun.com/app/docs/doc/816-5168/malloc-3c?a=view Non vedo alcuna indicazione che memalign() sia deprecato nel current glibc: http://cvs.savannah.gnu.org/viewvc/libc/malloc/malloc.h?revision=1.32&root=libc&view=markup – mrkj

7

Usa 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 è una sostituzione standard per memalign che, come si parla è obsoleto.