False Sharing and the Cache Line
Cache and NUMA effects are a recurring interview topic at the C++-first firms, and false sharing is the one that most reliably surprises people, because the program has no shared data and behaves as though it does.
The mechanism
Cache coherence operates on lines, typically 64 bytes (128 on some parts, Apple's M series among them), not on variables. When a core writes to a line, the protocol must invalidate every other core's copy of that line before the write can proceed. Two variables in the same line therefore behave, as far as the hardware is concerned, like one variable.
struct Counters {
std::atomic<long> producer_count; // written only by thread A
std::atomic<long> consumer_count; // written only by thread B
}; // both in one 64-byte line
Nothing here is shared. Each counter has exactly one writer, and the logic is correct. But every increment by A invalidates the line for B and vice versa, so each increment costs a coherence round trip between cores instead of a cache hit, and the pair runs an order of magnitude slower than the same code with the counters in separate lines.
The rest of this lesson is for subscribers
Unlock every lesson in Systems Programming for Trading, and every other premium course.
Subscribe to continueTest your knowledge
Keep reading Systems Programming for Trading
19 lessons in this course, and every other premium course, on one subscription.
- Every lesson in every course, with the worked examples and interactive simulators
- Graded questions on every lesson, with explanations for the wrong answers as well as the right one
- The trainers, timed assessments and brainteaser library that go with them