struct A
{
char c; float f; short s;
};
struct B
{
float f; short s; char c;
};
두 구조는 완전히 동일한 정보를 포함합니다. 이 예를 위해서; float 유형은 4 바이트, 짧은 유형은 2, 문자는 1 바이트를 사용합니다. 그러나 첫 번째 구조 A는 임의의 순서로 멤버가 있고 두 번째 구조 B는 멤버의 바이트 크기에 따라 순서가 지정됩니다 (특정 아키텍처에서는 다를 수 있음).이 예제에서 4 바이트 정렬을 사용하는 x86 Intel CPU 아키텍처를 가정합니다. 당신은 크기가 7 바이트로 기대하는 경우, 회원이 는 1 바이트 정렬을 사용하여 구조로 포장 된 것을 가정 할 것이다
printf("size of A: %d", sizeof (A)); // size of A: 12;
printf("size of B: %d", sizeof (B)); // size of B: 8;
: 이제 구조의 크기를 고려하십시오. 일부 컴파일러는 이것을 허용하지만 일반적으로 대부분의 컴파일러는 역사적인 이유로 (대부분의 CPU가 DWORD (더블 워드) 또는 QWORD (쿼드 워드) 범용 레지스터로 작업) 때문에 4 바이트 또는 8 바이트 정렬을 사용합니다.
패킹을 달성하기 위해 작업시 2 개의 패딩 메커니즘이 있습니다.
먼저 얻어진 바이트 크기를 바이트 - 정렬보다 작거나 같으면 다음 부재 (들) "병합"되는 바이트 - 정렬보다 바이트 크기 작은있는 각 부재. 구조체 B에서 멤버 s와 c는이 방식으로 병합 될 수 있습니다. 이들의 결합 된 크기는 c == 3 바이트 인 경우 s + 1 바이트의 경우 2 바이트입니다. < = 4 바이트 정렬 인 경우. 구조체 A의 경우 이러한 병합이 발생할 수 없으며 구조체의 패킹에서 각 멤버가 효과적으로 4 바이트를 소비합니다.
다음 구조가 정렬 경계에서 시작할 수 있도록 구조의 전체 크기가 다시 채워집니다. 예제 B에서 전체 바이트 수는 7이됩니다. 다음 4 바이트 경계는 바이트 8에 있으므로 구조에 1 바이트가 채워져 배열 할당이 긴밀한 인스턴스 순서로 허용됩니다.
Visual C++/GCC에서는 1 바이트, 2 및 2 배 이상의 배수가 서로 다른 정렬을 허용합니다.이것은 당신의 컴파일러가 당신의 아키텍처에 맞는 최적의 코드를 생성하는 능력에 반하는 것이라는 것을 이해하십시오. 실제로 다음 예제에서 각 바이트는 각 읽기 작업에 대해 싱글 바이트 명령어를 사용하여 단일 바이트로 읽습니다. 실제로 하드웨어는 캐시로 읽는 각 바이트를 포함하는 전체 메모리 라인을 가져오고 4 바이트가 동일한 DWORD에 있고 CPU 레지스터에 1 명령으로로드 될 수 있더라도 4 번 명령을 실행합니다.
이 밀접 2 심기구에 관한 것이다 할당 정렬 앞에서 설명한
#pragma pack(push,1)
struct Bad
{
char a,b,c,d;
};
#pragma pack(pop)
2. 그러나, llocation 정렬는 의 malloc/memalloc 변형에 지정 될 수있다 할당 기능. 따라서 구조체/객체 유형의 바이트 정렬이 제안하는 것보다 다른 (일반적으로 2보다 큰 배수) 정렬 경계에서 객체를 할당하는 것이 가능합니다.
size_t blockAlignment = 4*1024; // 4K page block alignment
void* block = malloc(sizeof(T) * count, blockAlignment);
코드는 다시 4096
이러한 할당 정렬을 사용하는 이유의 배수로 도착지 순전히 아키텍처 타입 T의 카운트 인스턴스의 블록을 배치되는 것이다. 예를 들어 페이지 정렬 주소에서 블록을 읽고 쓰는 것이 더 빠릅니다. 주소 범위가 캐시 계층에 적합하기 때문입니다. 다른 '페이지'로 분할되는 범위는 페이지 경계를 넘을 때 캐시를 휴지통으로 만듭니다. 서로 다른 미디어 (버스 아키텍처)는 서로 다른 액세스 패턴을 가지며 서로 다른 정렬을 통해 이점을 얻을 수 있습니다. 일반적으로 4, 16, 32 및 64 K 페이지 크기의 정렬은 일반적이지 않습니다.
네이티브 형식 대신 struct를 사용하여 다시 시도하십시오. –
'지정된 유형의 인스턴스에 필요한 정렬 (바이트 단위의 정수 (2의 제곱))을 반환합니다. '- http://en.cppreference.com/w/cpp/language/alignof. 'sizeof'는 크기를 바이트 단위로 제공합니다. – chris
아마도 언급 할만한 가치가 있습니다 - [sizeof는 항상 alignof의 배수입니다] (http://stackoverflow.com/questions/4637774/is-the-size-of-a-struct-required-to-be-an-exact-multiple -of-the-alignment-of-tha) – Steve314