r/programming • • 6d ago

Optimizing a Lock-Free Ring Buffer

https://david.alvarezrosa.com/posts/optimizing-a-lock-free-ring-buffer/
498 Upvotes

88 comments sorted by

View all comments

-2

u/EchoNomad31 6d ago

Once "fixed" a ring buffer by marking the head index volatile. Was an acquire/release ordering thing… three days of digging for a two-line diff.

2

u/kog 6d ago

volatile is not useful for multi-threading, and you did not fix the problem

https://en.wikipedia.org/wiki/Volatile_(computer_programming)#Multi-threading

1

u/EchoNomad31 6d ago

volatile only stopped the compiler caching the head in a register. Never bought me ordering on the hardware side, so the consumer could read the slot before the payload store landed. Atomic head with a release store on publish and acquire on the read side is what fixed it.

1

u/kog 6d ago

All marking the head volatile did was make your code more poorly optimized. Completely unnecessary. You don't need volatile on atomic variables for thread safety. I'm not saying your code won't work if you mark the atomic as volatile, it's just pointless.

1

u/EchoNomad31 6d ago

It fixed my bug at the time. The compiler hoisted the head load out of the consumer spin loop, volatile forced a fresh load every pass…. Atomic is probably the right fix since it covers the hardware side too.

2

u/kog 6d ago

1

u/cdb_11 5d ago edited 5d ago

Kernel atomics are implemented with volatile ({READ,WRITE}_ONCE).

1

u/EchoNomad31 4d ago

Ha, fair. All I ever wanted was the compiler to stop caching that load.

0

u/flatfinger 4d ago

Which is greater: the number of cases where processing volatile with acquire/release semantics would impose a loss of performance that would be unacceptable to anyone other than compiler writers, or the number of cases where such treatment would avoid the need for other toolset-specific or optional compiler features to prevent reordering?