Reputation: 43
I am trying to implement a int
counter which is always incremented by one thread (Thread1)
and always decremented by another (Thread2)
.
one option is to use std::atomic<int>
.
Although i got another idea where i have two variables say counterIncr
and counterDecr
.
Thread1
always increments counterIncr
, while Thread2 always decrements counterDecr
.
And I will use the sum of (counterIncr+counterDecr)
as my final result.
Does this have any performance advantage? Is this wait-free?
Upvotes: 0
Views: 1618
Reputation: 70106
If you need a result that is accessible at any time, using std::atomic
is the correct thing to do, and if "just a counter" is all you need, std::memory_order_relaxed
is sufficient, which is reasonably efficient.
Do however note that you still have significant bus overhead, so if you do millions of increments, this may become a limiting factor. Do not do this unless you only expect a few hundred or so increments total (in that case it doesn't matter), or unless you really need to be able to read the value any time.
If you need a final result after doing many calculations, it is much, much preferrable to join the two threads (or block them, or signal the main thread that you are done and no longer writing to the counters) and have each thread update only a per-thread counter non-atomically. You can use a reference or a per-reference lambda capture so the consuming thread has "easy" access to the result.
This will not hammer the bus and will run a lot faster, but of course you only have a valid result available at the end, not any time before that.
Upvotes: 4