另外在std :: atomic <double>上没有加起来非原子对应物

时间:2016-11-30 06:52:11

标签: c++ c++11 floating-point precision atomicity

我正在尝试使用带有此函数的比较和交换方案在循环中对双原子执行添加:

namespace my
{
    template<typename value_type>
    value_type atomic_add(std::atomic<value_type>& operand, value_type value_to_add)
    {
        value_type old = operand.load(std::memory_order_consume);
        value_type desired = old + value_to_add;
        while (!operand.compare_exchange_weak(old, desired, std::memory_order_release, std::memory_order_consume))
            desired = old + value_to_add;

        return desired;
    }
}

这在我的代码中使用如下:

[ size of containers = 62, scalar = 318.0, values in containers between 0.0 and 55.0, all values are of type double ]

for(size_t i = 0; i < container.size(); i++)
{
    my::atomic_add<double>(Q, container2[i] - std::pow(container3[i], 2) / scalar);
}

输出为0.57784502195324539

但是,将所有my_atomic替换为+=运算符,并将所有std::atomic<double>替换为double会产生0.52something,这更接近我的预期。

知道为什么会这样吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

我似乎已经解决了这个问题,因此我将发布一个答案作为其他开发人员的警示故事。

这是一个最小的工作示例:

202

其输出为d2.0似乎已初始化为std::atomic。这个故事的寓意是始终确保你的std::atomics被初始化为理智的价值。

此外,其他答案指出,将CopyAssignable存储在向量中通常是一个坏主意,因为它们不是CopyConstructible和{{1}}。