2009-12-17 8 views
16

Wie weisen Sie Speicher zu, der an einer bestimmten Grenze in C ausgerichtet ist (z. B. Cacheleitungsgrenze)? Ich suche nach einer malloc/free-ähnlichen Implementierung, die idealerweise so portabel wie möglich wäre - zumindest zwischen 32- und 64-Bit-Architekturen.Zuweisen und Freigeben von ausgerichtetem Speicher in C

Bearbeiten Hinzufügen: Mit anderen Worten, ich bin auf der Suche nach etwas, das sich wie (die jetzt obsolete?) memalign Funktion, die mit freien befreit werden kann.

+0

Haben Sie diese zwei Antworten auf SO überprüft: http://stackoverflow.com/questions/227897/solve-the-memory-alignment-in-c-interview-question-that-stumped-me/227900#227900 und http://stackoverflow.com/questions/1855896/memory-alignment-on-modern-processors? –

+0

Nicht ganz was ich suche. Ich möchte etwas, das mehr wie malloc funktioniert, gibt einen Wert zurück, der der ausgerichtete Zeiger ist, dann haben Sie eine andere Funktion, die frei ist, die auf diesem Zeiger aufgerufen wird. Wenn Sie eine Lösung wie die von Ihnen angegebenen anwenden, müssen Sie entweder zwei Werte umleiten oder die Ausrichtung neu berechnen, wann immer sie benötigt wird. Ich suche etwas Ähnliches wie memalign. Danke, dass du diese Antworten aussuchst. – fuad

+1

Es gibt 'posix_memalign()' auf entsprechenden Maschinen - hat eine andere Schnittstelle als 'memalign()'. –

Antwort

24

Hier ist eine Lösung, die den Aufruf von malloc kapselt, einen größeren Puffer für Ausrichtungszwecke reserviert und die ursprüngliche zugewiesene Adresse unmittelbar vor dem ausgerichteten Puffer speichert, damit ein späterer Aufruf frei wird.

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

mit den neuen Standards, sollten Sie überlegen, die Besetzung zu "long" mit ersetzen eine Umwandlung zu 'uintptr_t' –

+0

@ Jeroe Insbesondere der Code funktioniert nicht auf 64-Bit-Windows – user877329

+0

@Jerome - Irgendein bestimmter Grund, Sie sagen' malloc (Größe + ALIGN + sizeof (void *)) 'und nicht' malloc (Größe + ALIGN-1 + Größevon (void *)) '? Wenn Sie auf eine * n * -Byte-Grenze ausgerichtet sind, benötigen Sie nur höchstens * n * - 1 zusätzliche Bytes. –

3

Welchen Compiler benutzen Sie? Wenn Sie MSVC verwenden, können Sie versuchen _aligned_malloc() und _aligned_free().

+0

Suns Compiler für Solaris/SPARC und gcc für Linux/x86 – fuad

+1

Sieht so aus Sun unterstützt memalign(): http://docs.sun.com/app/docs/doc/816-5168/malloc-3c?a=view Ich sehe keine Hinweise, dass memalign() in der. Veraltet ist Aktuelle Glibc: http://cvs.savannah.gnu.org/viewvc/libc/malloc/malloc.h?revision=1.32&root=libc&view=markup – mrkj

7

Verwenden 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 ist ein Standard-Ersatz für memalign die, wie Sie ist veraltet erwähnen.

Verwandte Themen