문제

Windows의 인터 로크 함수를 사용하여 매우 간단한 스핀 록을 만들어 이중 코어 CPU (변수를 증가시키는 2 개의 스레드)에서 테스트했습니다.

프로그램은 정상적으로 작동하는 것 같습니다 (매번 동일한 결과를 제공합니다. 동기화가 사용되지 않은 경우에는 그렇지 않습니다). 인텔 병렬 검사관 인종 조건이 있다고 말합니다 값 += j (아래 코드 참조). 스핀 락 대신 중요한 섹션을 사용할 때 경고가 사라집니다.

내 스핀 락 구현이 정확합니까? 사용 된 모든 작업은 원자이며 적절한 메모리 장벽을 가지고 있으며 레이스 조건으로 이어지지 않기 때문에 정말 이상합니다.

class SpinLock
{
   int *lockValue;
   SpinLock(int *value) : lockValue(value) { }

   void Lock() {
      while(InterlockedCompareExchange((volatile LONG*)lockValue, 1, 0) != 0) {
          WaitABit();
      }
   }

   void Unlock() { InterlockedExchange((volatile LONG*)lockValue, 0); }
};

테스트 프로그램 :

static const int THREADS = 2;
HANDLE completedEvents[THREADS];
int value = 0;
int lock = 0; // Global.

DWORD WINAPI TestThread(void *param) {
    HANDLE completed = (HANDLE)param;
    SpinLock testLock(&lock);

    for(int i = 0;i < 1000*20; i++) {
        for(int j = 0;j < 10*10; j++) {
            // Add something to the variable.
            testLock.Lock();
            value += j;
            testLock.Unlock();
        }
    }
    SetEvent(completed);
}

int main() {
   for(int i = 0; i < THREADS; i++) {
        completedEvents[i] = CreateEvent(NULL, true, false, NULL);
   }
   for(int i = 0; i < THREADS; i++) {
        DWORD id;
        CreateThread(NULL, 0, TestThread, completedEvents[i], 0, &id);
   }

   WaitForMultipleObjects(THREADS, completedEvents, true, INFINITE);
   cout<<value;
}
도움이 되었습니까?

해결책

병렬 검사관의 문서 데이터 레이스 Windows에서 레이스를 수정하기 위해 중요한 섹션 또는 뮤텍스를 사용하는 것이 좋습니다. 병렬 검사관이 발명 할 수있는 다른 잠금 메커니즘을 인식하는 방법을 알고 있음을 암시하는 것은 없습니다.

새로운 잠금 메커니즘을 분석하기위한 도구는 코드를 통해 가능한 모든 경로를 보는 정적 도구 인 경향이 있습니다. 병렬 검사관의 문서는 코드를 한 번 실행한다는 것을 암시합니다.

새로운 잠금 메커니즘을 실험하고 싶다면 학술 문헌에 사용 된 가장 일반적인 도구는 다음과 같습니다. 스핀 모델 검사기. 또한 있습니다 ESP, 주 공간을 줄일 수 있지만 동시 문제에 적용되었는지, 또한 이동성 워크 벤치 Pi-Calculus에서 문제를 소파 할 수 있다면 분석을 제공합니다. 인텔 병렬 검사관은 이러한 도구만큼 복잡한 것처럼 보이지 않고 휴리스틱을 사용하여 일반적으로 발생하는 문제를 확인하도록 설계되었습니다.

다른 팁

나와 비슷한 상황에 처한 다른 가난한 사람들의 경우 : 인텔은 이런 종류의 일을 정확히 수행하기위한 일련의 포함과 도서관을 제공합니다. 해당 자료에 대한 Inspector 설치 디렉토리 (설치 디렉토리에 포함, lib32 및 lib64 포함)를 확인하십시오. 사용 방법에 대한 문서화 (2018 년 6 월 현재 인텔은 링크를 일관성있게 유지하는 데 아무런 관심이 없습니다) :

https://software.intel.com/en-us/inspector-user-guide-windows-apis-por-custom-synchronization

3 가지 기능이 있습니다.

void __itt_sync_acquired(void *addr)
void __itt_sync_releasing(void *addr)
void __itt_sync_destroy(void *addr)

나는 그것이 다음과 같이 구현되어야한다고 확신합니다.

class SpinLock
{
   long lockValue;
   SpinLock(long value) : lockValue(value) { }

   void Lock() {
      while(InterlockedCompareExchange(&lockValue, 1, 0) != 0) {
          WaitABit();
      }
   }

   void Unlock() { InterlockedExchange(&lockValue, 0); }
};
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top