← Concepts

阅读中文版本

False Sharing

False sharing happens when independent variables used by different cores land in the same cache line, making cores invalidate each other through coherence traffic without any logical sharing.

concurrency

Definition

Cache coherence operates at line granularity, typically 64 bytes. When two threads on different cores write distinct variables in the same line, each write invalidates the other core cached copy. The variables are logically private but physically shared, and performance degrades as if they contended — usually a multi-fold slowdown discovered only by profiling.

Context and scope

Hits counters in per-thread statistics, adjacent fields in hot structs, and array-based work partitions. Diagnosed with perf c2c and cache-miss counters.

Common misconceptions

  • Only shared data causes contention — coherence works per cache line; data you never share can still share a line
  • More threads make it faster — each additional writer multiplies invalidation traffic on the line
  • The compiler or JVM fixes padding automatically — allocation layout often keeps adjacent fields together by default

Anti-patterns

  • Aggregating per-thread counters into one array of structs updated by neighboring workers
  • Placing a read-mostly config field next to a write-hot counter in the same cache line
  • Padding blindly across the whole codebase and bloating memory footprint without measuring first

Related concepts

Related examples

Authoritative source

https://en.wikipedia.org/wiki/False_sharing

What it is

CPUs do not track per-variable ownership; they track per-line ownership. Two cores writing different addresses inside one line fight for the line, bouncing it through coherence protocol states. The program is correct but slow, and the slowdown is invisible to the source code.

How it works

On each write, the core acquires exclusive ownership of the line, invalidating other copies. The previous writer core refetches on its next write, ping-ponging the line. Detection: cache miss counters clustered on one address range, or perf c2c highlighting lines hit from many threads. Fix: pad or rearrange so each hot writer owns a full line.

When to fix

Per-thread statistics structs, ring buffer headers, task queue metadata, and anything with one field per worker sitting contiguously. Align hot mutable fields to line boundaries or group by writer instead of by category.

Pitfalls

Padding costs memory and cache density for cold data — measure first. GC languages resist layout control: use array-of-struct with padded slots or off-heap structures. False sharing can appear after a harmless-looking refactor merges two hot fields into one struct.