我想使用一个通常计数为2 ^ 40的原子计数器(多线程计算),所以我不能直接使用32位int原子计数器。我还没有c ++ 11(我将迁移到它,但现在还没有,因为这对我来说是个代价),我必须在32位和64位平台上进行编译。
我目前使用QT,因此可以使用QAtomicInt。
这就是我的想法:
(initialization...)
QAtomicInt counterLo = 0;
QAtomicInt counterHi = 0;
void increment()
{
int before = counterLo.fetchAndAddOrdered(1);
if(before==INT_MAX)
{
counterHi.fetchAndAddOrdered(1); //Increment high word
counterLo.fetchAndAddOrdered(INT_MAX); //Increments low word to -1
counterLo.fetchAndAddOrdered(1); //Increments low word to 0
}
}
uint64_t value()
{
//Wait until the low word is non-negative
int lo = counterLow;
while(lo<0)
lo = counterLow;
return (uint64_t)counterHi * ((uint64_t)INT_MAX+1) + (uint64_t)lo;
}
它是否正确?我已经尝试过使用互斥量进行计数,但是性能却下降了10%左右。这称为每秒1百万次,在8个线程之间共享(用于蒙特卡洛模拟的样本计数器)
谢谢!
最佳答案
这不是整体原子,请参见以下示例:hi=0,lo=INT_MAX
T1呼叫value()
,获取lo=INT_MAX
,被中断
T2呼叫increment()
增至1
T1恢复并读取counterHi
,得到1,返回值2 ^ 32 + INT_MAX
这可能不是您想要的。您能否仅拆分示例空间并让每个线程计算n / 8个项目而不必争夺锁?