我想使用原子计数器(多线程计算),它通常计数到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%左右。这大约每秒被调用100万次,在8个线程之间共享(蒙特卡洛模拟的样本计数器)
谢谢!
发布于 2013-03-19 19:17:50
这不是整体的原子,请看下面的例子:
hi=0,lo=INT_MAXvalue(),获取lo=INT_MAX,被中断increment()递增hi to 1counterHi,获取1,返回值2^32 + INT_MAX 这可能不是您想要的。难道你不能分割你的样本空间,让每个线程计算n/8个项目,而不争用一个锁吗?
发布于 2013-03-19 19:25:48
我建议使用保护(互斥或临界区)。
https://stackoverflow.com/questions/15497287
复制相似问题