14 ms·
A properly efficient sequence lock (no compare exchange or full acquire fence, relaxed loads for reads--which are less expensive on ARM than acquire loads, for
by Jweb_Guru 3y ago
A properly efficient sequence lock (no compare exchange or full acquire fence, relaxed loads for reads--which are less expensive on ARM than acquire loads, for good architectural reasons) isn't actually possible to write in C++ and I believe this was in fact a motivation for why Java atomics are the way they are. See https://www.hpl.hp.com/techreports/2012/HPL-2012-68.pdf https://www.hpl.hp.com/techreports/2012/HPL-2012-68.pdf. I suspect this is why Java added load-load.
- gpderetta 3y agoAs per the paper to express it optimally in c++ it requires the compiler to special case +=0. I don't think any compiler does ot yer unfortunately.
- Jweb_Guru 3y agoCompilers are usually very reluctant to add "surprising" optimizations to atomics, even if they're fully justified by the standard, because (1) there are a lot of compiler bugs and/or holes in the standard that are only exposed after combining multiple optimizations involving atomics, (2) most programs explicitly use atomics only rarely, making it not the most productive thing to optimize, and (3) the programs and libraries that do use them are often reliant on them for synchronization, "liveness," or performance behavior that's not mandated by the standard. Common pathological examples include checks that assume the compiler won't skip assigning values if it can prove there's some obscure possible execution where the intermediate value can never be read, assuming that checking the result of a relaxed load in an if statement will guarantee that accesses run in the if will be sequenced after the read, etc.
- bonzini 3y agoIt has always been possible to write it in C++ since C++11, since acquire fences are cheap enough, but not in Java until loadFence() was introduced in JDK 8. The paper you cite proposed compiling an atomic add-zero to MFENCE+MOV, which is 5 times slower than the rest of the seqlock access, just because fences were not in Java at the time and are "a very difficult-to-use and C++11/C11-specific construct". That part of the paper has never made sense to me, and certainly does not matter now that Java has fences. Just wrap the seqlock into a primitive that hides the fence and call it a day.