32位比较和交换64位字

时间:2016-08-01 05:26:21

标签: c++ c gcc atomic compare-and-swap

假设我有64位字(high32,low32),我在32位变量(比如low32)上做__sync_val_compare_and_swap。如果两个线程同时在high32和low32上尝试CAS,它们都可以成功吗?

1 个答案:

答案 0 :(得分:2)

在Windows 64位上,相邻int的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;
}