[英]How to understand RELAXED ORDERING in std::memory_order (C++)
[英]Example of misuse of std::memory_order::relaxed in C++ Standard [algorithms.parallel.exec/5 in n4713]
在 C++ 标准中滥用std::memory_order::relaxed
的例子之一:
std::atomic<int> x{0};
int a[] = {1,2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) {
x.fetch_add(1, std::memory_order::relaxed);
// spin wait for another iteration to change the value of x
while (x.load(std::memory_order::relaxed) == 1) { } // incorrect: assumes execution order
});
然后它说,
上面的例子取决于迭代的执行顺序,如果两个迭代在同一个执行线程上按顺序执行,则不会终止。
问题:
评论说,“不正确:假定执行顺序”。 什么是“假定的执行顺序”? 我想念它。
“上面的例子取决于迭代的执行顺序”中的“迭代”指的是什么? 这是否意味着while循环中的迭代? 还是它指的是std::for_each
的迭代?
如果std::for_each
的迭代由不同的线程并行执行,那么迭代/线程之一不会退出是否仍然正确? 因为x.fetch_add(1, std::memory_order::relaxed)
是原子的,所以一个线程将使x
1 而另一个线程将使x
2 并且不可能有 x == 1 两个线程。 不?
“不正确:假定执行顺序”。 什么是“假定的执行顺序”?
它假设 lambda 的主体由多个线程而不是一个线程执行。 该标准宁愿说它可以并行执行。
“上面的例子取决于迭代的执行顺序”中的“迭代”指的是什么?
它可能是指另一个线程执行lambda。 但标准不保证有另一个线程。 见execution_policy_tag_t :
parallel_policy
执行策略类型,用作消除并行算法重载的歧义并指示并行算法的执行可以并行化的唯一类型。 使用此策略调用的并行算法中元素访问函数的调用(通常指定为 std::execution::par)被允许在调用线程或由库隐式创建的线程中执行以支持并行算法执行。 在同一线程中执行的任何此类调用相对于彼此的顺序是不确定的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.