MSDN에 있는 글을 옮겨와 봤습니다^^

 

다른 프로세서에서 사용되고 있는 복수의 동시실행 태스크가 같은 캐시라인에 배치되어 있는 변수에 쓰기를 하면 거짓 공유가 발생한다. 하나의 태스크가 어떤 변수에 쓰기를 하면 양쪽 변수의 캐시라인이 무효화된다. 캐시라인이 무효화 될 때마다 재 로딩이 필요하게 된다. 즉 거짓 공유가 발생하면 애플리케이션의 성능이 저하할 위험이 크다.

 

long count1 = 0L;

long count2 = 0L;

concurrency::parallel_invoke(

   [&count1] {

      for(int i = 0; i < 100000000; ++i)

         ++count1;

   },

   [&count2] {

      for(int i = 0; i < 100000000; ++i)

         ++count2;

   }

);

long count = count1 + count2;

위의 코드는 태스크에 공유 변수를 사용하지 않기 위해 count1, count2로 변수를 나누어서 사용하고 있다. 그래서 일견 보기에는 서로 독립적으로 실행될 것이라고 생각할 수 있다. 그러나 위에 설명했듯이 count1 count2는 서로 같은 캐시라인에 배치될 확률이 높아서 결과적으로 거짓 공유가 발생한다.

 

이 문제를 해결하기 위해서는 아래처럼 메모리 정렬에 의해 서로 다른 캐시라인에 배치되도록 한다.

__declspec(align(64)) long count1 = 0L;     

__declspec(align(64)) long count2 = 0L;     

concurrency::parallel_invoke(

   [&count1] {

      for(int i = 0; i < 100000000; ++i)

         ++count1;

   },

   [&count2] {

      for(int i = 0; i < 100000000; ++i)

         ++count2;

   }

);

long count = count1 + count2;

핵심은 __declspec(align(64))으로 메모리 캐시 사이즈가 64바이트 이하인 경우 같은 캐시라인을 사용하지 않도록 해준다.

 

 

__declspec 설명

http://blog.naver.com/riverrun27/40126498899

 

 

저작자 표시
신고
by 흥배 2014.02.03 08:00
| 1 |