In another threadt0m was pointing to std::atomic_flag as a guaranteed lock-free atomic variable.
However, from what I’ve read, I suspect that, in practice, std::atomic<int> and std::atomic<float> store and load might be compiled as lock-free for all “ordinary” PC/Mac computers.
In other words has anybody some statistics on the result of is_lock_free() on std::atomic<int> and std::atomic<float> variables?
I’m fully aware of the risk of using methods that only work “in practice” but when dealing with code written by others, sometimes it is hard to justify a big investment to fix something that is already working.
I found this interesting thread on stackoverflow:
Anybody has a good read on this topic with more context?
I don’t know any good article about this. But here is what I know:
AFAIK all primitive 32bit data types like float and int are lock-free on x64 systems. But there is no guarantee that an atomic struct that contains two floats or more data is lock-free. In this case, you can use is_lock_free() to test this.
Don’t access atomic types in sample-based DSP algorithms directly. Store them into a local variable first to make it possible for the compiler to optimize the code.
You most likely don’t run into problems when you are not using atomics for shared primitive data types like floats or ints at a first sight.
Nonetheless, you should use them to avoid subtle hard to reproduce and time-consuming bugs:
I understand that there is absolutely no guarantee for struct’s but I’ve fixed the format of my initial post to focus my question on the int and float types.
For non atomic int’s and float’s I read about the possibility of one thread running in a CPU core storing the value in the cache, and another thread running in another CPU core reading from its own cache without knowing about the other CPU’s cache. Multi-core CPU’s and software are becoming more ubiquitous nowadays so I’m afraid that it can be dangerous to rely on what we have seen in practice to work so far. Particularly, those are edge cases that can be very hard to notice in real life, specially when dealing with music but can get your software to play the wrong note in a bad day (although we could argue that there is not such a thing like a “wrong” note if it is played with attitude )
Recently i read a paper about the OOTA/RFUB problem for memory_order_relaxed atomic variables. Nothing related directly to your question, but a clear warning about how concurrency can be a nightmare if you don’t stick to good practices and if you go in the UB world.
Very interesting too. It might not be related to how I formulated my question but you have guessed it correctly: I’m currently trying to understand well the behavior of std::atomic and I was also struggling to infer good practices regarding the use of memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst.
Actually, in this kind of topics, beginner texts can be more confusing than helpful though. The author introduces his own atomic library instead of discussing std::atomic (to be fair it was published in 2013 when C++11 was recent).
Mintomic is a very small part in all the blog posts (anyway it is not used anymore).
The C++11 atomics are largely covered.
It is for me the best resource for beginners (easier at start that the Anthony Williams book for instance).
My opinion is probably biased since i learned all (at first) with that blog!