3

From the documentation is pretty clear that the difference between them is that std::barrier can be used more than once and std::latch can only be used once.

That sounds to me like std::latch is simply a special case of std::barrier that adds a limitation instead of a feature. On top of that the documentation says that a call to count_down with an n greater than the internal counter is undefined behavior, so this limitation has to be enforced programatically.

So why do we need std::latch?

My only guess is that it is possible to implement std::latch differently at the hardware level in a way that improves performance.

What is the reason?

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
imreal
  • 10,178
  • 2
  • 32
  • 48
  • 2
    Might be analogous to `std::lock_guard` and `std::unique_lock` - the former coming with a more light-weight implementation... – Aconcagua Jun 27 '18 at 14:48
  • 3
    Sometimes you'll see more limited versions of some features that are less powerful but also cheaper (in terms of memory or other computational resource) to use. For example [`std::mutex`](https://en.cppreference.com/w/cpp/thread/mutex) is simpler, cheaper and less powerful [`std::recursive_mutex`](https://en.cppreference.com/w/cpp/thread/recursive_mutex). I'm not sure this is the same situation, but it's worth a thought. – François Andrieux Jun 27 '18 at 14:49
  • @FrançoisAndrieux That is what I guessed, however I would like to know for sure. – imreal Jun 27 '18 at 14:51
  • Also see : https://stackoverflow.com/questions/48985967/where-can-we-use-stdbarrier-over-stdlatch – Sander De Dycker Jun 27 '18 at 14:54
  • @SanderDeDycker I saw that question, it is more about the "when to use" instead of the "why". – imreal Jun 27 '18 at 14:56
  • @imreal : I know - that's why I didn't mark as duplicate. But I thought it might still be interesting to you (or future readers). – Sander De Dycker Jun 27 '18 at 15:02
  • Close voters this is not an opinion based question, it is clear there is an objective difference between them. – imreal Jun 27 '18 at 15:04

1 Answers1

8

API wise, std::latch lets you count down without blocking. Imagine you have to render 172 furbles before some other task starts. You can set up a latch with a value of 173, and have each thread that completes a furble count down the latch, and have the thread that is supposed to consume those furbles wait on the latch.

The worker threads will count down, but not wait as they have other furbles to render. If they go to sleep, they'd use some other synchronization primitive to do it.

std::barrier only lets you count down while blocking. It could not be used to permit 10 threads to render 172 furbles. The only thing you can do as a thread on a barrier is to reach it, or decide you aren't participating anymore.

There may also be hardware differences, but their APIs are quite different and replacing latch use with barriers is not possible.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • I don't understand how `count_down` differs from `arrive_and_drop`. – imreal Jun 27 '18 at 14:59
  • 2
    @imreal: I realize that this is an old question but it may still be relevant: `count_down()` can be called multiple times from the same thread while `arrive_and_drop()` cannot. The implication is that you can't use `arrive_and_drop()` from tasks executed on some kind of thread pool as calling `arrive_and_drop()` on the same `std::barrier` twice from the same thread is undefined behavior. Also, `arrive_and_drop()` _may_ block until the `std::barrier` completion phase while `count_down()` can at most block on the `std::latch`'s synchronization. – Dietmar Kühl Apr 29 '21 at 12:07