2009-12-17 6 views
16

C (예 : 캐시 라인 경계)의 특정 경계에 맞춰진 메모리를 어떻게 할당합니까? 나는 적어도 32 비트와 64 비트 아키텍처 사이에서 가능하면 휴대 할 수있는 구현과 같은 malloc/free를 찾고있다.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에 ​​대한 호출을 캡슐화하고 더 큰 버퍼를 정렬 목적으로 할당하며 나중에 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

새로운 표준으로 캐스트를 'long'으로 바꾸는 것을 고려해야합니다. 'uintptr_t'에 캐스트 –

+0

@Jermoe 특별히 64 비트 Windows에서 코드가 작동하지 않습니다 – user877329

+0

@Jerome - 'malloc (size + ALIGN + sizeof (void *)) size + ALIGN-1 + sizeof (void *))'? * n * 바이트 경계에 맞추려면 최대 * n * - 1 여분의 바이트 만 필요합니다. –

3

어떤 컴파일러를 사용하고 있습니까? MSVC를 사용중인 경우 _aligned_malloc()_aligned_free()을 사용해보세요.

+0

Solaris/SPARC 용 Sun 컴파일러 및 Linux/x86 용 gcc – 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위한 표준 교체입니다.