Andrey Semashev wrote:
If we adopt this philosophy, shouldn't there be `opaque_` and `_and_test` increments and decrements, too? `lock inc [r]` instead of `lock add [r], 1`, or even `mov eax, 1; lock add [r], eax` if the compiler can't be trusted to optimize, which we assume.
To some extent, I'm already doing this:
https://github.com/boostorg/atomic/blob/develop/include/boost/atomic/detail/...
In general though, there has to be a reasonable balance between the library usability and efficiency. I think the current interface is quite close to it.
The interface strikes me as heavily influenced by what g++ can (__builtin_constant_p) and cannot (figure out that the result is not needed) do. The order of adding the functions probably also plays a part; were `op_and_test` added first, `opaque_op` probably wouldn't have been. It's interesting to play and see what gets generated when. For instance, clang++ 3.6 figures out by itself that in `x1.fetch_and_add( 1 );` the result is not used, and generates `lock inc`. https://godbolt.org/g/7TFQ2V How does it manage to do that, if you're using assembly `xadd`, I don't know. https://github.com/boostorg/atomic/blob/develop/include/boost/atomic/detail/... The standard atomic fetch_add consistently generates `lock inc` by the way. g++ trunk similarly manages to replace the xadd with add.