C++20 std::barrier
has arrive_and_wait
method, which is what pretty much every synchronization barrier implementation has.
But it also has separate arrive
and wait
. Why do these functions exist?
You might like to know that there's a std::barrier in C++20. Your wait is what C++20 calls arrive_and_wait. Your generation is what C++20 calls the "phase."
I've implemented a barreir in C++ close to one showed here. In the project code it's used only with two threads and seems to work. A synthetic test didn't expose any flaws too. But I suspect that on some machines it segfaults and/or falls through wait () call.
Consequently, the atomic operations for std::shared_ptr<T> are deprecated with C++20. What's next? With C++20, threads can be cooperatively interrupted. Let me show you in my next, what that means.
Wait System Call in C. A call to wait() blocks the calling process until one of its child processes exits or a signal is received. After child process terminates, parent continues its execution after wait system call instruction. Child process may terminate due to any of these: It calls exit();
OK, so you've got a bunch of threads that have to do some kind of synchronized tasks. These tasks are grouped into phases: the tasks from one phase will use data produced by tasks from a previous phase, and all previous phase work must be done before any next-phase work can start. Let us call any work that requires data from a previous phase "in-phase" work.
However, let's say that not everything you need to do actually requires data from a previous phase. There could be some individual work items that a thread could perform that doesn't read data from a previous phase. Let's call this "out-of-phase" work.
Note that this is "out-of-phase" relative to a particular barrier. It could be that the work is in-phase of a different barrier.
If you try to do this out-of-phase work before calling arrive_and_wait
, then you could be blocking all of the other threads from doing something even though you are done with the actual work they're waiting on. Depending on the balance between in-phase and out-of-phase work, that could be a lot of wasted performance.
So if a thread has finished its in-phase work and has some out-of-phase work to do, it can arrive
. This potentially frees up all of the other threads if they too are finished with their in-phase work. The thread can then go process some out-of-phase work potentially asynchronously with work being done from the next phase. Once the out-of-phase work is done, the thread can wait
on the token generated by its call to arrive
, which if the next phase has started, will return without blocking.
Indeed, if the amount of in-phase work is much less than the amount of out-of-phase work, then this pattern means that threads almost never block. The barrier just acts as a multi-thread atomic ordering operation, never a blocking one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With