2009-12-17 2 views
16

Как вы распределяете память, которая выровнена с определенной границей в C (например, граница строки кэша)? Я ищу malloc/бесплатную реализацию, которая в идеале была бы максимально переносимой, по крайней мере, между 32 и 64-битными архитектурами.Как выделить и освободить выровненную память в C

Редактировать добавить: Другими словами, я ищу что-то, что будет вести себя как (теперь устаревшее?) memalign функция, которую можно освободить, используя бесплатно.

+0

Вы проверили эти два ответа на 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

Не совсем то, что я ищу. Я хотел бы что-то, что больше похоже на malloc, возвращает одно значение, которое является выровненным указателем, а затем имеет другую функцию, похожую на free, вызываемую этим указателем. Применение такого решения, как те, которые вы указали, требует либо прохождения двух значений, либо пересчета выравнивания всякий раз, когда это необходимо. Я ищу что-то похожее на memalign. Спасибо, что указали на эти ответы. – fuad

+1

Существует 'posix_memalign()' на соответствующих машинах - имеет другой интерфейс из 'memalign()'. –

ответ

24

Это решение, которое инкапсулирует вызов в malloc, выделяет больший буфер для цели выравнивания и сохраняет исходный выделенный адрес непосредственно перед выравниваемым буфером для последующего вызова на бесплатный.

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

с новыми стандартами, вы должны рассмотреть возможность замены актера на 'long' с помощью a cast to 'uintptr_t' –

+0

@Jermoe В частности, код не работает на 64-разрядной Windows – user877329

+0

@Jerome - Любая конкретная причина, по которой вы говорите' malloc (размер + ALIGN + sizeof (void *)) ', а не' malloc (площадь + ALIGN-1 + SizeOf (недействительными *)) '? Если вы согласуетесь с границей * n * -byte, тогда вам понадобится не более * n * - 1 лишних байтов. –

3

Какой компилятор вы используете? Если вы находитесь на MSVC, вы можете попробовать _aligned_malloc() и _aligned_free().

+0

Компилятор Sun для Solaris/SPARC и gcc для Linux/x86 – fuad

+1

Похож Sun поддерживает memalign(): http://docs.sun.com/app/docs/doc/816-5168/malloc-3c?a=view Я не вижу признаков того, что memalign() устарел в текущий glibc: http://cvs.savannah.gnu.org/viewvc/libc/malloc/malloc.h?revision=1.32&root=libc&view=markup – mrkj

7

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 является стандартной заменой memalign, который, как вы упоминаете является устаревшим.

Смежные вопросы