2017-05-04 9 views
2

4 바이트의 자연 정렬을 가정합니다.캐시에로드하는 동안 데이터 정렬

struct Node 
{ 
int data; 
char c_data; 
}; 
int main() { 
int global = 10; 
struct Node N; 
for (register int i = 0; i < 10; i++) 
cout << global << N.data << endl; } 

캐시 라인 크기가 16 바이트이고 내 프로그램이 루프에서이 두 변수를 액세스하는 경우 어떻게 이러한 변수가 캐시에 존재합니까? 다른 모든 것은 레지스터 변수라고 가정합니다.

동일한 캐시 라인에서?

On 다른 캐시 라인?

동일한 캐시 라인 인 경우, 각 구성원은 캐시의 4 바이트 정렬 주소에서 시작합니까? like 전역 변수는 [0,3]에서 스팬하고 N은 [4,7]에서 스팬합니다. 또는 구조체가 char을 가지고 있다면 캐시 라인의 [5]부터 시작할 수 있습니다.

기본적으로 캐시에 데이터를로드하는 동안 구조체의 크기 또는 첫 번째 멤버를 기준으로 정렬이 고려됩니까?

+0

데이터는 데이터 크기가 아닌 라인 크기에 따라 캐시 라인에로드되므로 메모리의 데이터 구성/정렬이 캐시에 반영됩니다. – LPs

답변

2

캐시 사용 방법은 주로 코드에 달려 있습니다. 즉, 질문에 언급했지만 게시하지 않은 이론적 인 루프입니다. 루프 전에 사용 된 다른 변수가 어디에 할당되는지에 따라 우선 순위가 적용될 수 있습니다. 특정 시스템을 염두에두고 상세한 소스 코드가 주어 지더라도 정확히 어떤 일이 일어날지를 정확하게 알려주는 것은 매우 어렵습니다.

메모리에 인접하게 할당 된 변수는 캐시 친화적입니다. 기본적으로 캐시가 효율적 이도록 RAM에서 캐시로 전송 될 수있는 인접 할당 된 변수 덩어리가 있어야합니다. 변수가 완전히 다른 세그먼트에 있으면 "캐시 누락"이 발생합니다. 즉, 무언가가 캐시에서 버려 져야하고 다른 것이 RAM에서 읽혀 져야합니다.

예를 들어 스택에 할당 된 로컬 변수가있는 경우 모두가 캐시에 저장하는 것이 좋습니다. 귀하의 경우에는

global은 메모리의 .data 섹션에 할당되고 N.bss 섹션에 할당, 그래서 그들은 모든 인접하지 않은 그 이유에 대해 동일한 캐시 라인에로드되지 않습니다. 귀하의 경우 전체 캐시 토론이 적용되지 않는다는 것을 의미합니다.

: 대신 struct Node N = {1};을 쓴 경우

는 다음 코드에 같은 장소에서 사용하는 경우 변수는, (나는 격렬하게 추측하고있어) 결국 .data이 같은 할당 된 것이라고 가정하는 것이 합리적 보인다

4 bytes - global 
4 bytes - N.data 
4 bytes - N.c_data 

여기서 정렬은 CPU에 맞게 조정됩니다. 캐시는 RAM을 미러링 할 뿐이며, "정렬에 맞게 이동 한 것"이 없습니다. 변수가 RAM에 할당되었을 때 정렬은 이미 처리되었습니다.

이 전체 청크는 잠재적으로 캐시로 읽힐 수 있습니다.

+0

답을 바탕으로 global과 N을 지역 변수로 유지하도록 질문을 수정했습니다. 이제 내 질문은 글로벌 또는 캐 틀린 라인의 N 주소가 4의 배수 인 오프셋이 될지 여부입니다. 0,4,8처럼. 또는 캐시 라인의 오프셋 3, 5에서 시작할 수 있습니까? 나는 여기서 건축 지식을 놓칠 수있다. 정렬 관점에서 데이터를 가져 와서 캐시에 저장하는 방법을 안내하십시오. –

+1

@AnupBuchke 컴파일러/링커가 RAM의 정렬 된 주소에 변수를 넣으면 변수가 정렬됩니다. 캐시는 0 ~ _n_ 바이트의 데이터를 포함하는 RAM의 동일한 사본입니다. – Lundin

+0

고마워. 도움이됩니다. 나는 링커가 그들을 RAM에 넣는 방법을 찾을 것이다. –