32-битное сравнение и замена на 64-битное слово

Скажем, у меня есть 64-битное слово (high32, low32), и я делаю __sync_val_compare_and_swap на 32-битной переменной (скажем, low32). В случае, когда два потока одновременно пытаются CAS на high32 и low32, могут ли они оба преуспеть?

1

Решение

В 64-битных окнах CAS для соседних целых всегда успешно выполняется независимо от выравнивания и пересечения строк кэша (если только в моем тестовом приложении нет ошибки). Я только протестировал Windows 7, 64 бит.

РЕДАКТИРОВАТЬ:
Вероятно, именно так CAS будет работать на всех современных чипах Intel независимо от ОС. Я работал на 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;
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector