宽松的原子计数器安全吗? [英] Is a relaxed atomic counter safe?

查看:77
本文介绍了宽松的原子计数器安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据C ++ 11内存模型,以下代码是否保证返回计数器的期望值(40,000,000)? (仅限于x86).

Is the following code guaranteed to return the expected value of counter (40,000,000), according to the C++11 memory model? (NOT limited to x86).

#include <atomic>
#include <thread>
using namespace std;

void ThreadProc(atomic<int>& counter)
{
    for (int i = 0; i < 10000000; i++)
        counter.fetch_add(1, memory_order_relaxed);
}

int main()
{
    #define COUNT 4
    atomic<int> counter = { 0 };
    thread threads[COUNT] = {};

    for (size_t i = 0; i < COUNT; i++)
        threads[i] = thread(ThreadProc, ref(counter));

    for (size_t i = 0; i < COUNT; i++)
        threads[i].join();

    printf("Counter: %i", counter.load(memory_order_relaxed));
    return 0;
}

特别是,松弛原子会进行协调,以使两个线程不会同时读取当前值,独立地递增当前值,而不会写出它们的递增值,从而有效地丢失其中之一吗?

In particular, will relaxed atomics coordinate such that two threads will not simultaneously read the current value, independently increment it, and both write their incremented value, effectively losing one of the writes?

规范中的某些行似乎表明在上面的示例中计数器必须始终为40,000,000.

Some lines from the spec seem to indicate that counter must consistently be 40,000,000 in the above example.

[注意:指定memory_order_relaxed的操作可以通过 关于内存排序.实现仍必须保证 对特定原子对象的任何给定原子访问都是不可分割的 关于对该对象的所有其他原子访问. —尾注

[Note: operations specifying memory_order_relaxed are relaxed with respect to memory ordering. Implementations must still guarantee that any given atomic access to a particular atomic object be indivisible with respect to all other atomic accesses to that object. — end note

.

原子读取-修改-写入操作应始终读取最后一个值 (按修改顺序)写了与 读取-修改-写入操作.

Atomic read-modify-write operations shall always read the last value (in the modification order) written the write associated with the read-modify-write operation.

.

对特定原子对象M的所有修改都在某些情况下发生 特定的总顺序,称为M的修改顺序.如果A和B 是原子对象M和A之前发生的修改(如 B),那么A的修改顺序应在B之前 M,定义如下.

All modifications to a particular atomic object M occur in some particular total order, called the modification order of M. If A and B are modifications of an atomic object M and A happens before (as defined below) B, then A shall precede B in the modification order of M, which is defined below.

本演讲还支持上述代码不受种族歧视的观念. https://www.youtube.com/watch? v = KeLBd2EJLOU& feature = youtu.be& t = 1h9m30s

This talk also supports the notion that the above code is race free. https://www.youtube.com/watch?v=KeLBd2EJLOU&feature=youtu.be&t=1h9m30s

在我看来,原子操作有 个不可分的顺序,但我们不能保证该顺序是什么.因此,所有增量都必须先于另一方"进行,而不能进行我上面描述的比赛.

It appears to me that there is an indivisible ordering of the atomic operations, but we have no guarantees what the order is. So all increments must take place 'one before the other' without the race I described above.

但是随后有一些事情可能指向另一个方向:

But then a few things potentially point in the other direction:

实施应使原子存储对原子负载可见 在合理的时间内.

Implementations should make atomic stores visible to atomic loads within a reasonable amount of time.

我从一位同事那里获悉,萨特的谈话中存在已知的错误.虽然我还没有找到任何资源.

I've been informed by a coworker that there are known mistakes in Sutter's talk. Though I've yet to find any sources for this.

C ++社区的多个成员比我所暗示的要聪明得多,因为可以缓冲一个轻松的原子加法,以便随后的轻松的原子加法可以对过时的值进行读取和操作.

Multiple members of the C++ community smarter than I have implied that a relaxed atomic add could be buffered such that a subsequent relaxed atomic add could read and operator on the stale value.

推荐答案

问题中的代码是无种族限制的;所有增量都是有序的,并且保证了40000000的结果.
您问题中的参考文献包含标准中所有相关的引号.

The code in your question is race free; all increments are ordered and the outcome of 40000000 is guaranteed.
The references in your question contain all the relevant quotes from the standard.

说原子存储应该在合理时间内可见的部分仅适用于单个存储.
在您的情况下,计数器通过原子级的read-modift-write操作递增,并且保证按修改顺序最新执行.

The part where it says that atomic stores should be visible within a reasonable time applies only to single stores.
In your case, the counter is incremented with an atomic read-modift-write operation and those are guaranteed to operate on the latest in the modification order.

C ++社区的多个成员(...)暗示可以缓冲轻松的原子加法,以便随后的轻松的原子加法可以读取陈旧值并对其进行操作.

Multiple members of the C++ community (...) have implied that a relaxed atomic add could be buffered such that a subsequent relaxed atomic add could read and operator on the stale value.

这是不可能的,只要修改是基于原子的read-modify-write操作.
如果标准不能保证可靠的结果,原子增量将毫无用处

This is not possible, as long as the modifications are based on atomic read-modify-write operations.
Atomic increments would be useless if a reliable outcome was not guaranteed by the standard

这篇关于宽松的原子计数器安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆