2016-08-01 79 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