2016-08-01 80 views
1

假设我有一个64位字(高32位,低32位),我对32位变量(比如low32)做了__sync_val_compare_and_swap。在两个线程同时在high32和low32上尝试使用CAS的情况下,它们都可以成功吗?在64位字上进行32位比较和交换

+0

我不明白downvote。很高兴知道2个相邻的__int32是否会产生干扰?如果不占用相同的缓存行,它们会干涉吗?我假设一切都需要对齐,但如果不是,两个相邻的未对齐__int32会干涉。 – johnnycrash

+1

@johnnycrash:这一天日益恶化。至少,我们需要迫使人们在对某些事情下调时发表评论。 – arunmoezhi

+0

猜猜没有人有答案。你可以用无限循环中的两个线程来测试它,每个线程都使用CAS。看看CAS是否失败。 – johnnycrash

回答

2

在Windows 64位上,无论对齐方式如何,无论缓存行是否交叉(除非我的测试应用程序有错误),相邻ints上的CAS总是成功。我只测试了Windows 7,64位。

编辑: 这可能是CAS如何工作在所有现代英特尔芯片,无论操作系统。我正在使用I7。

#include <stdio.h> 
#include <windows.h> 

volatile __declspec(align(64)) char a[128]; 
int _nAlign = 0; 

DWORD WINAPI ThreadProc(LPVOID lpThreadParameter) 
{ 
    auto iElem = (int)lpThreadParameter; 
    volatile auto* p = (int*)(a + _nAlign + sizeof(int) * iElem); 
    for (long long i = 0; i < 1000000000; ++i) { 
     int nOld = *p, nNew = nOld + 1; 
     if (InterlockedCompareExchange((DWORD*)p, (DWORD)nNew, (DWORD)nOld) != nOld) 
      return 1; 
    } 
    return 0; 
} 

int main(int argc, char* argv[]) 
{ 
    if (argc == 2) 
     _nAlign = atoi(argv[1]); 
    HANDLE aThread[2]; 
    for (int i = 0; i < 2; ++i) { 
     aThread[i] = CreateThread(NULL, 0, ThreadProc, (LPVOID)i, 0, NULL); 
     SetThreadAffinityMask(aThread[i], 1<<(2*i)); // hyperthreading is on, so make sure on actual separate cores 
    } 
    WaitForMultipleObjects(2, aThread, true, INFINITE); 
    DWORD aCode[2]; 
    if (!GetExitCodeThread(aThread[0], &aCode[0]) || !GetExitCodeThread(aThread[1], &aCode[1])) 
     printf("GetExitCodeThread failed\n"); 
    if (aCode[0] || aCode[1]) 
     printf("CAS failed\n"); 
    else 
     printf("CAS Succeeded\n"); 
    return 0; 
} 
+0

感谢您的详细验证。我猜想CAS都会成功。但我会尝试记录缓存统计信息,看看是否会导致缓存未命中。 – arunmoezhi