英特尔督察报告数据争在我的自旋锁执行(Intel Inspector reports a data

2019-07-19 06:49发布

我在Windows中使用互锁函数提出了一个非常简单的自旋锁并测试它的双核CPU(即递增变量两个线程);

该方案似乎工作正常(它提供了相同的结果每一次,这是不是在没有使用同步的情况下),但英特尔Parallel Inspector中说有在值+ = 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;
}

Answer 1:

Parallel Inspector中对文档数据争建议使用临界区或互斥来修复Windows上比赛。 有什么也没有,这表明Parallel Inspector中知道如何识别任何其他锁定机制可能会创造。

对于新的锁定机制的分析工具往往是其看通过代码每一个可能的路径静电工具,Parallel Inspector中的文档意味着它一旦执行代码。

如果你想用新的锁定机制来尝试,我在学术文献中见过最常用的工具是自旋模型检查 。 还有ESP ,这可能会减少国家的空间,但我不知道它是否被应用到并发问题,也是移动工作台这会给出一个分析,如果你能在沙发pi演算您的问题。 英特尔Parallel Inspector中似乎并不喜欢那样复杂,因为这些工具,而是旨在检查使用启发式经常发生的问题,任何东西。



Answer 2:

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

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

有3个功能:

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


Answer 3:

我敢肯定它应该实现如下:

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

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

   void Unlock() { InterlockedExchange(&lockValue, 0); }
};


文章来源: Intel Inspector reports a data race in my spinlock implementation