mardi 8 octobre 2019

Example of misuse of std::memory_order::relaxed in C++ Standard

One of the examples of misuse of std::memory_order::relaxed in C++ Standard:

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

And then it says,

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.

Questions:

  1. The comment says, "incorrect: assumes execution order". What's the "assumed execution order"? I miss it.

  2. What does the "iterations" refer to in "The above example depends on the order of execution of the iterations"? Does it mean the iteration in while loop? Or does it refer to the iteration of std::for_each?

  3. If the iterations of std::for_each are executed in parallel by different threads, isn't it still true that one of the iterations/threads won't exit? Because x.fetch_add(1, std::memory_order::relaxed) is atomic and so one thread will make x 1 and another will make x 2 and it is impossible to have x == 1 for both thread. No?

Aucun commentaire:

Enregistrer un commentaire