Home Knowledge Base False Sharing

False Sharing is the insidious parallel performance pathology where two or more threads on different cores modify independent variables that happen to reside on the same cache line — causing the hardware cache coherence protocol to repeatedly invalidate and reload the entire cache line across cores, creating catastrophic cache line "ping-pong" that can slow down parallel code by 10-100x despite the threads sharing no logical data.

How False Sharing Occurs

CPU caches operate on cache lines (typically 64 bytes). When Thread 0 on Core 0 writes variable A and Thread 1 on Core 1 writes variable B, and A and B are within the same 64-byte cache line, the coherence protocol (MESI/MOESI) invalidates Core 1's copy when Core 0 writes, and vice versa. Each write forces the other core to fetch the updated cache line from the L3 cache or the writing core's L1 — a round trip of 40-100 cycles per access instead of 3-4 cycles for a local L1 hit.

Classic Example

int counters[NUM_THREADS]; // Adjacent in memory!
void work(int tid) {
    for (int i = 0; i < 1000000; i++)
        counters[tid]++;  // Each thread increments its own counter
}

counters[0] through counters[15] all live in a single 64-byte cache line. Despite each thread modifying only its own counter, every increment invalidates the line for all other cores. Performance: 10-50x slower than the single-threaded case.

Detection

Solutions

1. Padding: Insert unused bytes between variables to place them on separate cache lines:

struct PaddedCounter {
    int value;
    char padding[60]; // Ensure each counter occupies its own 64-byte line
};
PaddedCounter counters[NUM_THREADS];

2. Alignment: Use compiler attributes (alignas(64) in C++11, __attribute__((aligned(64))) in GCC) to force cache line alignment.

3. Thread-Local Accumulation: Each thread accumulates into a local variable (register), writing to the shared array only once at the end.

4. Data Structure Redesign: Replace arrays of per-thread values with per-thread structures spaced at cache line boundaries. Many parallel libraries (Intel TBB, Java @Contended) provide padded per-thread containers.

False Sharing is the performance trap that punishes the illusion of independence — threads that believe they are working on private data are secretly fighting over cache lines, and the hardware coherence protocol silently converts what should be embarrassingly parallel code into a serialized disaster.

false sharing cachecache line contentionfalse sharing performancecache coherence overheadcache line padding

Explore 500+ Semiconductor & AI Topics

From EUV lithography to CUDA optimization — search the full knowledge base or chat with our AI assistant.