2012-12-26 3 views
2

그 라인의 사본을 보유한 코어/캐시가 더 많은 경우 캐시 작성이 완료되는 데 더 오래 걸리는지 알아봐 주시겠습니까? 나는 또한 얼마나 오래 걸리는지 측정/정량화하려고합니다.무효화 할 캐시 쓰기가 더 많은 캐시에서 더 오래 걸립니까?

구글에서 유용한 것을 찾지 못했습니다. 직접 측정하는 데 문제가 있으며, 현대 프로세서에서 발생할 수있는 많은 것들 때문에 측정 한 것을 해석하는 데 어려움이 있습니다. (재정렬, 프리 페치, 버퍼링과 하나님을 알고 무엇을)

세부 사항 :

을 측정 내 기본 프로세스는 것은 대략 다음과 같이

write soemthing to the cacheline on processor 0 
read it on processors 1 to n. 

rdtsc 
write it on process 0 
rdtsc 

나는조차 확실하지 않다하는 지침 최종적으로 시간 측정 전에 쓰기/무효화가 완료되었는지 확인하기 위해 실제로 프로세스 0에서 읽기/쓰기에 사용하십시오.

원자 적 교환 (__sync_fetch_and_add())을 사용하는 순간 나는이 작업의 길이 (스레드를 무효로하는 수가 아님) 자체가 중요하다고 생각합니다. 내가 원하는 것을 측정하지 마라.

또한 읽기, 쓰기, 메모리 차단 (__sync_synchronize())을 시도했습니다. 이것은 내가 볼 것으로 기대하는 것보다 더 많이 보입니다. 하지만 마지막 rdtsc가 발생할 때 쓰기가 끝났는지 확실하지 않습니다.

내 생각에 CPU 내부에 대한 지식은 다소 제한적입니다.

어떤 도움을 주셔서 감사합니다.

ps : * 측정을 위해 linux, gcc 및 pthreads를 사용합니다. *이 알고리즘은 병렬 알고리즘을 모델링 할 때 유용합니다.

편집 : 때문에, 일주일 정도에서

이 (내일 휴가를가는) 나는 (경우 누군가가 관심에서) 좀 더 연구를하고 내 코드 및 메모를 게시 여기에 연결합니다 내가 쓸 수있는 시간은 제한적입니다.

+1

gcc 버전이 최신 버전 인 경우 많이 개선 된 [__atomic] (http://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html) 내장 함수를 사용할 수 있습니다. [MESI] (http://en.wikipedia.org/wiki/MESI) 캐시 통합 프로토콜을 읽어 볼 수도 있습니다. 유일한 프로토콜은 아니지만 원자 연산이 구현되는 방식에 대해 더 잘 이해할 수 있습니다. –

답변

4

매우 긴 답변을 작성하고 정확하게 작동하는 방법을 설명한 다음 정확한 정보를 충분히 알지 못했습니다. 그래서 나는 더 짧은 대답을 할 것입니다. ...

그래서 한 프로세서에 뭔가 쓸 때, 이미 그 프로세서 캐시에 없다면, 그 프로세서를 읽어 들인 후 프로세서가 데이터의 경우 실제 쓰기를 수행합니다. 그렇게하면 시스템의 다른 모든 프로세서에 캐시 무효화 메시지를 보냅니다. 그러면 모든 콘텐츠가 삭제됩니다. 다른 프로세서가 "더러운"내용을 가지고 있다면 자체적으로 데이터를 기록하고 무효화를 요청합니다.이 경우 첫 번째 프로세서는 쓰기를 완료하기 전에 데이터를 RELOAD해야합니다 (그렇지 않으면 동일한 캐시 라인의 다른 요소 파괴 될 수 있음).

캐시 라인에 관심이있는 다른 모든 프로세서에는 다시 캐시로 읽어 들여야합니다.

__sync_fetch_and_add()는 x86에서 "lock"접두사를 사용하지만 다른 프로세서는 다를 수 있지만 "명령어 별 잠금"을 지원하는 프로세서에 대한 일반적인 개념은 대략 동일합니다.] - "I want 이 캐시 라인은 독점적으로, 다른 모든 사람들은 그것을 포기하고 무효화하십시오. " 첫 번째 경우와 마찬가지로 프로세서는 다른 프로세서가 더러워진 것 같은 것을 다시 읽어야 할 수도 있습니다.

메모리 장벽으로 인해 데이터가 "안전하게"업데이트되지 않습니다. "이 instructon이 완료 될 때까지는 (이전의 메모리로) 모든 프로세서에서 볼 수 있습니다."라는 것을 확실히 알 수 있습니다.

프로세서 사용을 최적화하는 가장 좋은 방법은 가능한 한 공유하지 말고 특히 "허위 공유"를 피하는 것입니다. 몇 년 전 벤치 마크에서,이 [simplifed]와 같은 구조가 있었다 : 때마다 thread1은 X [0]에 쓴

struct stuff { 
    int x[2]; 
    ... other data ... total data a few cachelines. 
} data; 

void thread1() 
{ 
    for(... big number ...) 
     data.x[0]++; 
} 

void thread2() 
{ 
    for(... big number ...) 
     data.x[1]++; 
} 

int main() 
{ 
    start = timenow(); 

    create(thread1); 
    create(thread2); 

    end = timenow() - start; 
} 

때문에

, thread2의 프로세서가 그것을 제거했다가있어 X의 사본 [1] , 반대의 경우도 마찬가지입니다. 결과는 SMP 테스트 [방금 thread1을 실행하는 것]이 약 15 배 느리게 실행된다는 것입니다. 이 같은 구조체를 변경하여 :

struct stuff { 
    int x; 
    ... other data ... 
} data[2]; 

우리가 1 개 스레드 변형 [몇 퍼센트를 제공하거나 걸릴]

오른쪽의 200 %를 가지고

void thread1() 
{ 
    for(... big number ...) 
     data[0].x++; 
} 

, 그래서 프로세서는 큐를 가지고 프로세서가 메모리에 기록 할 때 쓰기 작업이 저장되는 버퍼의 수를 나타냅니다. 메모리 장벽 (mfence, sfence 또는 lence) 명령어는 프로세서가 다음 명령어로 진행하기 전에 미해결 읽기/쓰기, 쓰기 또는 읽기 유형 연산이 완전히 완료되었는지 확인하기위한 것입니다. 일반적으로 프로세서는 다음 명령을 통해 유쾌한 방법으로 계속 진행할 것이며 결과적으로 메모리 작동이 어떤 식 으로든 완료됩니다. 현대의 프로세서는 많은 양의 병렬 연산과 버퍼를 가지고 있기 때문에, 결국 실제로 어떤 일이 결국 끝나기까지 상당한 시간이 걸릴 수 있습니다. 따라서 진행하기 전에 무언가가 실제로 완료되었는지를 확인하는 것이 중요 할 때 (예를 들어, 비디오 메모리에 일련의 지침을 작성한 경우 해당 지침의 실행을 시작하려는 경우, 'instruction'쓰기가 실제로 끝났고 프로세서의 다른 부분이 아직 끝내지 못하고 있으므로 sfence을 사용하여 쓰기가 실제로 발생했는지 확인하십시오. 하지만 당신이 생각하는 것 같아요.)

+0

원자 교환은 측정을위한 올바른 작업입니까? 내 측정에서는 무효화 할 코어의 수에 관계없이 스레드의 총 수 (프로그램에서 생성되는 공회전 스레드 수 - 이상한가?)가 중요합니다. –

+0

당신은 당신이 기대하는 것과 그 숫자가 당신이 기대하는 것과 어떻게 다른지에 대한 많은 세부 사항을 정말로 게시하지 않았습니다. 잠긴 (__sync ...) 작업을 사용하지 않으면 많은 차이가 있습니까? –

+0

읽기, 쓰기, 메모리 장벽 (__sync_synchronize)을 수행하면 유휴 스레드 수가 증가해도 증가하지 않지만 무효 코어 수는 증가합니다 (이것은 예상 한 것입니다.)하지만 이것이 맞는지 확실하지 않습니다. 내가 측정하고 싶은 것은 무엇입니까? 그것은 알고 있습니까?). 방금 읽는다면, 그것은 magicked 떨어져서 쓰고 나는 rdtsc주기 자체가 ~ 20-40, 아무런 차이도 없다. 나는 이것에 대해 몇 시간 (1 주일 정도)을 보낼 것이다. 그러나 이것은 매우 중요한 질문이 아니기 때문에 나의 시간은 제한적이다. 그러나 원한다면 내 물건과 메모를 끝에 게시 할 수 있습니다. –

4

캐시 쓰기는 캐시 라인을 더럽 히기 전에 라인 소유권을 가져야합니다. 프로세서 아키텍처에 구현 된 캐시 일관성 모델 인 에 따라이 단계에 소요되는 시간이 다릅니다. 내가 아는 가장 일반적인 일관성 프로토콜은 다음과 같습니다

  • 스누핑 일관성 프로토콜 : 모든 캐시 즉 모든 메모리 요청이 CPU를 증가 등 모든 CPU 즉 비 확장에 방송 할 필요가 캐시 메모리 라인 주소 라인을 모니터링 할 수 있습니다.
  • 디렉토리 기반 Coherence 프로토콜 : 많은 cpus에서 공유되는 모든 캐시 라인은 디렉토리에 보관됩니다. 따라서 소유권을 무효화/확보하는 것은 브로드 캐스트가 아닌 지점 간 (point-to-point) CPU 요청이므로 확장 성이 뛰어나지 만 디렉터리가 단일 경합 지점이므로 지연이 발생합니다.

대부분의 CPU 아키텍처는 PMU (perf monitoring unit)라고하는 것을 지원합니다.이 유닛은 캐시 히트, 미스, 캐시 쓰기 대기 시간, 읽기 대기 시간, tlb 히트 등과 같은 많은 것들에 대해 카운터를 내 보냅니다.이 정보가 사용 가능한지 알아 보려면 cpu 설명서를 참조하십시오.

+0

그래서 현대의 x86 프로세서는 어떻게되었나? 그리고 더 많은 코어에서 더 오래 걸립니까? 어떻게 측정 할 수 있습니까? –

관련 문제