我做了一个非常简单的调节锁使用互锁的功能在窗户和测试,它对双重核CPU(两个线程,增加一个变量);

该程序似乎运作"确定"(这给出了同样的结果每次,这不是这种情况时,没有同步使用),但是 英特尔的平行检查 说有一场比赛的状况 值+=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;
}
有帮助吗?

解决方案

并行检查的文件 数据的比赛 建议使用的一个关键部分的或互斥解决种族上的窗户。有没有在其它建议,并检查员知道如何认识的任何其他锁定机构你可能会发明。

工具,用于分析的新的锁定机制往往是静态工具,看看每一个可能的路径穿过码的、并行的检查的文件意味着执行代码一次。

如果你想尝试新颖的锁定机制,最常见的工具,我已经看到了用于学术文献是的 旋转模型检查.还有 ESP, ,这可能会减少国家的空间,但我不知道,如果它是适用的并发问题,并且还的 流动性工作台 这将使一个分析如果你可以睡沙发你的问题在pi微积分。英特尔的平行检查似乎并不像任何复杂,因为这些工具,而是设计来检查为经常发生的问题采用启发。

其他提示

有关类似的情况给我其他贫困乡亲:英特尔确实提供了一套包括和准确地做这样的事情库。检查在检查安装目录(你会看到\包括\ LIB32和\安装目录lib64目录)的那些材料。关于如何使用这些文档(如2018年6月,虽然英特尔在乎保持一致的链接没有):

的https://软件.intel.com / EN-US /检查员用户引导窗口的API换定制同步

有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