对64位字进行32位比较和交换

32bit compare and swap on a 64 bit word

本文关键字:比较 交换 32位 64位      更新时间:2023-10-16

假设我有一个64位字(high32,low32),我对一个32位变量(比如low32)执行__sync_val_compare_and_swap。在两个线程同时尝试在high32和low32上执行CAS的情况下,它们都能成功吗?

在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 failedn");
    if (aCode[0] || aCode[1])
        printf("CAS failedn");
    else
        printf("CAS Succeededn");
    return 0;
}