
왜 C언어에서 double형 변수는 8byte로 정렬되는가 ?
링크텍스트
메모리에서 Data type alignment 를 읽는데 한 부분이 이해가 안가서 질문
32 비트 머신에서 double형 변수는 8바이트 경계에 할당 될 것이고 2번의 메모리 리딩 사이클 (메모리 읽기 횟수) 를 요구한다. (메모리) 뱅크의 수에 따라 64비트 머신에서는 double 변수는 8byte 경계에 할당 될 것이고 메모리 리딩 사이클은 1번을 요구 한다.
내 질문은 왜 변수들이 4바이트 경계가아닌 8바이트 경계에 할당되는가? 입니다.
데이터를 2^N (2의 N승) 경계에 정렬하는것은 캐시 라인 경계를 따라 값이 나눠질 가능성을 피하기 위해서 입니다.
x86-32 프로세서는 double 형 변수를 최대 두번 32비트 메모리 읽기를 통해 어떤 워드 경계(word boundary) 에서도 가져올 수 있습니다. (사실 8바이트든 아니든 상관없음)
만약 값이 캐시 라인 경계를 통해 나누어져 있다면, 2번째 워드를 가져오는 시간은 꽤 길어질것입니다. 왜냐하면 메모리의 2번째 캐시라인에서 값을 가져와야 하기 때문입니다. 이것은 불필요한 성능저하를 만듭니다.
page boundaries를 벗어나지 않기 위한 정렬 방법론 입니다.
데이터를 가져오는 중간에 페이지폴트가 발생할 가능성을 피하는 것 입니다.
그래서 성능을 이유로 8바이트 경계로 정렬하는것인데 컴파일러가 이걸 알고 알아서 해주는 것 입니다.
cf.) Cache line boundary란 ?
링크텍스트
Cache line splits 이 발생하는 시나리오 : 데이터를 읽거나 쓰려는데 데이터의 한 부분이 1번 캐시라인에 있고 나머지는 인접한 2번 캐시라인에 있다고 하면 발생가능
인텔 아키텍처에서 캐시라인은 64B임, 따라서 캐시라인은 64의 배수로 시작해야한다.
예로 0x200 주소가 한 캐시라인이고 0x240 이 다음 캐시라인일때
DWORD 를 0x23f 부터 읽는다고 하면 , 캐시라인 스플릿이 발생한다.
WORD = 16 bit (4byte)
DWORD = 32 bit (8byte)
I was reading a article about data types alignment in memory(here) and I am unable to understand one point i.e.
Note that a double variable will be allocated on 8 byte boundary on 32 bit machine and requires two memory read cycles. On a 64 bit machine, based on number of banks, double variable will be allocated on 8 byte boundary and requires only one memory read cycle.
My doubt is: Why double variables need to be allocated on 8 byte boundary and not on 4 byte? If it is allocated on 4 byte boundary still we need only 2 memory read cycles(on a 32 bit machine). Correct me if I am wrong.
Also if some one has a good tutorial on member/memory alignment, kindly share.
The reason to align a data value of size 2^N on a boundary of 2^N is to avoid the possibility that the value will be split across a cache line boundary.
The x86-32 processor can fetch a double from any word boundary (8 byte aligned or not) in at most two, 32-bit memory reads. But if the value is split across a cache line boundary, then the time to fetch the 2nd word may be quite long because of the need to fetch a 2nd cache line from memory. This produces poor processor performance unnecessarily. (As a practical matter, the current processors don't fetch 32-bits from the memory at a time; they tend to fetch much bigger values on much wider busses to enable really high data bandwidths; the actual time to fetch both words if they are in the same cache line, and already cached, may be just 1 clock).
A free consequence of this alignment scheme is that such values also do not cross page boundaries. This avoids the possibility of a page fault in the middle of an data fetch.
So, you should align doubles on 8 byte boundaries for performance reasons. And the compilers know this and just do it for you.