Recently, when working with C atomics, I've noticed that there are two variants: a "normal" version, whose order is seq_cst, and an "explicit" version, where the programmer is free to choose memory ordering:
relaxed : there are no synchronization guarantees between what threads see
acq_rel : after an acquire operation, the thread is synchronized with the one which released the atomic (all its writes become visible).
seq_cst : a global order is enforced between all seq_cst operations.
Seeing as using relaxed or even acq_rel may save many unnecessary memory synchronizations compared to the "default" of seq_cst, the compiler would gain a lot by recognizing cases where it can be safely downgraded (in the case of a counter variable, for example).
If it can do this, why not apply this logic everywhere and remove the "explicit" versions, because the compiler can figure out the least-constraining memory order while still preserving program integrity?
Or is this problem "unsolvable" in the same sense that detecting all possible memory leaks or illegal array accesses can be caught by the compiler in some special cases, but in the end the programmer must manage it?