C++ 标准 [algorithms.parallel.exec/5 in n4713 中误用 std::memory_order::relaxed 的示例]

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
});

然后它说,

The above example depends on the order of execution of the iterations, and will not terminate if both iterations are executed sequentially on the same thread of execution.

问题:

  1. 评论说,"incorrect: assumes execution order"。 "assumed execution order" 是什么?很怀念

  2. "iterations"在"The above example depends on the order of execution of the iterations"中指的是什么?这是否意味着 while 循环中的迭代?或者它指的是 std::for_each?

  3. 的迭代
  4. 如果std::for_each的迭代是由不同的线程并行执行的,那iterations/threads其中一个不退出不也是真的吗?因为 x.fetch_add(1, std::memory_order::relaxed) 是原子的,所以一个线程会使 x 1 而另一个线程会使 x 2 并且两个线程都不可能有 x == 1。没有?

"incorrect: assumes execution order". What's the "assumed execution order"?

它假定 lambda 的主体由多个线程而不是一个线程执行。该标准说它 可以 并行执行。

What does the "iterations" refer to in "The above example depends on the order of execution of the iterations"?

可能是指lambda被另一个线程执行了。但标准不保证有另一个线程。见 execution_policy_tag_t:

parallel_policy The execution policy type used as a unique type to disambiguate parallel algorithm overloading and indicate that a parallel algorithm's execution may be parallelized. The invocations of element access functions in parallel algorithms invoked with this policy (usually specified as std::execution::par) are permitted to execute in either the invoking thread or in a thread implicitly created by the library to support parallel algorithm execution. Any such invocations executing in the same thread are indeterminately sequenced with respect to each other.