我想使用一个通常计数为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个项目而不必争夺锁?

10-04 19:48