posix_memalign/memalign의 기능
어떤 기능이 있는지 이해하려고 합니다.memalign()
그리고.posix_memalign()
사용 가능한 문서를 읽는 것은 도움이 되지 않았습니다.
어떻게 작동하는지, 어떤 용도로 사용하는지 누가 좀 알려주시겠어요?또는 사용 예를 제시해 주십시오.
Linux 메모리의 구조를 이해하려고 합니다만, 독자적인 심플한 메모리 풀(저 플래그멘테이션 힙)을 쓸 필요가 있습니다.
반면에.malloc
는, 얼라인먼트를 가질 수 있는 메모리 청크를 제공합니다(유일한 요건은 실장이 서포트하는 가장 큰 프리미티브 타입으로 얼라인먼트를 할 필요가 있습니다).posix_memalign
는 요청된 정렬이 보장되는 메모리 청크를 제공합니다.
그 결과, 예를 들어 posix_memalign(&p, 32, 128)
는 128바이트의 메모리 청크로 시작 주소가 32의 배수임을 보증합니다.
이것은, 특정의 얼라인먼트에 준거한 메모리가 필요한 다양한 저레벨 조작(SSE 명령(DMA) 사용 등)에 도움이 됩니다.
Oli의 답변과 더불어 더 중요한 문제를 지적하고 싶습니다.
최근의 x86 아키텍처에서는 메모리에서 캐시로 가져올 수 있는 최소 데이터 양인 캐시 라인은 64바이트입니다.구조 크기가 56바이트라고 가정하면 대규모 배열이 있습니다.하나의 요소를 조회할 때 CPU는 2개의 메모리 요청을 발행해야 합니다(캐시라인 중간에 있는 경우에도 2개의 요청을 발행할 수 있습니다).이는 메모리를 기다려야 하고 캐시를 더 많이 사용하기 때문에 성능에 좋지 않습니다. 따라서 결과적으로 캐시 누락 비율이 높아집니다.이 경우 posix_memalign을 사용하는 것만으로는 충분하지 않지만 64바이트 경계에 맞게 구조를 패딩하거나 압축해야 합니다.
40 바이트의 구조를 가지는 것은 불운에 지나지 않습니다.
malloc
는 항상 모든 원시 유형에 필요한 최대 정렬로 설정된 메모리를 반환합니다.이렇게 하면malloc
필요한 모든 유형의 메모리를 저장할 수 있습니다.설명에 대한 나의 이해posix_memalign
는, 얼라인먼트로 지정한 주소의 배수가 되는 메모리 위치를 반환하는 것입니다.
커스텀 메모리 풀을 쓸 때 이것이 얼마나 도움이 될지는 잘 모르겠습니다만, 실장 방법의 예를 제시해 보았습니다.다른 점은 이 예와 같습니다.malloc_aligned
로워야 합니다.free_aligned
,에서는posix_memalign
하면 .free
.
#include <stdlib.h>
#include <stdio.h>
void *malloc_aligned(size_t alignment, size_t bytes)
{
// we need to allocate enough storage for the requested bytes, some
// book-keeping (to store the location returned by malloc) and some extra
// padding to allow us to find an aligned byte. im not entirely sure if
// 2 * alignment is enough here, its just a guess.
const size_t total_size = bytes + (2 * alignment) + sizeof(size_t);
// use malloc to allocate the memory.
char *data = malloc(sizeof(char) * total_size);
if (data)
{
// store the original start of the malloc'd data.
const void * const data_start = data;
// dedicate enough space to the book-keeping.
data += sizeof(size_t);
// find a memory location with correct alignment. the alignment minus
// the remainder of this mod operation is how many bytes forward we need
// to move to find an aligned byte.
const size_t offset = alignment - (((size_t)data) % alignment);
// set data to the aligned memory.
data += offset;
// write the book-keeping.
size_t *book_keeping = (size_t*)(data - sizeof(size_t));
*book_keeping = (size_t)data_start;
}
return data;
}
void free_aligned(void *raw_data)
{
if (raw_data)
{
char *data = raw_data;
// we have to assume this memory was allocated with malloc_aligned.
// this means the sizeof(size_t) bytes before data are the book-keeping
// which points to the location we need to pass to free.
data -= sizeof(size_t);
// set data to the location stored in book-keeping.
data = (char*)(*((size_t*)data));
// free the memory.
free(data);
}
}
int main()
{
char *ptr = malloc_aligned(7, 100);
printf("is 5 byte aligned = %s\n", (((size_t)ptr) % 5) ? "no" : "yes");
printf("is 7 byte aligned = %s\n", (((size_t)ptr) % 7) ? "no" : "yes");
free_aligned(ptr);
return 0;
}
GNU C에서 posix_memalign을 사용하는 경우 두 번째 파라미터는 2의 거듭제곱일 뿐만 아니라 size of(void*)의 배수여야 합니다.이 요건은 memalign 기능의 요건과는 다릅니다.memalign 기능은 2의 전력만을 필요로 합니다.
int
__posix_memalign (void **memptr, size_t alignment, size_t size)
{
void *mem;
/* Test whether the SIZE argument is valid. It must be a power of
two multiple of sizeof (void *). */
if (alignment % sizeof (void *) != 0
|| !powerof2 (alignment / sizeof (void *))
|| alignment == 0)
return EINVAL;
void *address = RETURN_ADDRESS (0);
mem = _mid_memalign (alignment, size, address);
if (mem != NULL)
{
*memptr = mem;
return 0;
}
return ENOMEM;
}
weak_alias (__posix_memalign, posix_memalign)
posix_memalign 구현의 첫 번째 if 조건을 보면 정렬이 size of(void*)의 배수인지 여부를 확인합니다.
어떻게 동작하는지는 구현에 따라 다릅니다.이 함수의 목적은 n바이트 정렬된 메모리 블록을 제공하는 것입니다(블록의 시작 주소는 n의 배수입니다).
memalign은 사용되지 않기 때문에(참조: man 페이지), 여기서는 malloc()와 posix_memalign()의 차이만 설명합니다.malloc()는 8바이트 정렬(RHEL 32비트의 경우 등)이지만, posix_memalign()의 경우 정렬은 사용자가 정의할 수 있습니다.이 사용법을 알기 위해서는 mprotect()를 사용하여 메모리 속성을 설정하는 것이 좋습니다.mprotect()를 사용하려면 메모리 포인터가 PAGE 정렬되어 있어야 합니다.따라서 posix_memalign()을 호출하고 페이지 크기를 정렬하면 반환된 포인터는 쉽게 mprotect()로 전송하여 읽기/쓰기 실행 가능 속성을 설정할 수 있습니다.(예를 들어 데이터를 메모리 포인터에 복사한 후 데이터를 읽기 전용 속성으로 설정하여 수정하지 않도록 할 수 있습니다)."contrac()"의 반환된 포인터는 여기서 사용할 수 없습니다.
언급URL : https://stackoverflow.com/questions/6563120/what-does-posix-memalign-memalign-do
'programing' 카테고리의 다른 글
문자열 배열을 ArrayList로 변환 (0) | 2022.07.26 |
---|---|
사용 시기: Java 8+ 인터페이스 기본 방식과 추상 방식 비교 (0) | 2022.07.26 |
Executor Service 스레드 및 스레드 풀 이름 지정 (0) | 2022.07.26 |
Vuex와 Redux의 불변성 접근방식의 차이점 (0) | 2022.07.26 |
여러 vuex createNamesched에 대한 베스트 프랙티스는 무엇입니까?도우미? (0) | 2022.07.26 |