.. /index

Mechanical Sympathy

Mechanical Sympathy

Mechanical sympathy is Martin Thompson's term — borrowed from Jackie Stewart's racing philosophy — for designing software that works with the hardware rather than against it. The thesis: at the limits of performance, language choice matters less than understanding the machine. Java volatile ping-pong runs at 50 ns; C++ atomic ping-pong runs at 45 ns on the same hardware. The 10% gap is rounding error compared to the 100× cost of a single algorithm choice that fights the cache coherence protocol. The LMAX Disruptor is the canonical demonstration: a Java program that beats most C/C++ queues by aligning every design decision with the underlying hardware reality.

The core claim

The gap between languages, at the inter-thread communication layer, is far smaller than developers expect:

Implementation Latency per op
Java volatile (ping-pong) 50 ns
C++ std::atomic (ping-pong) 45 ns
Rust SPSC ring buffer comparable to C++

All three emit LOCK-prefixed x86 instructions and bottleneck on the MESI/MOESI protocol. The compiler's job is to emit the right instructions; once it does, the hardware decides the speed. Languages diverge meaningfully only at higher levels — GC pauses, allocation patterns, FFI overhead — which can usually be engineered around.

What "designing with the hardware" actually means

The Disruptor's design choices are the canonical checklist:

Each of these is a hardware-aware decision. Together they pull a Java program down to 52 ns per hop on 2011-era hardware — a number that approaches the bare cache-coherence floor of that machine.

The corollary: hardware sets the ceiling

Mechanical sympathy implies an inverse principle: no amount of clever software can go faster than the hardware allows. The cache-coherence floor on AMD Zen 3 is 16 ns; no algorithm can transfer a cache line between cores faster than that. The L3 hit latency is ~40 cycles; nothing reads from L3 faster. DRAM round-trip is ~80 ns; nothing reads from RAM faster.

This is why optimization at the limits looks like:

  1. Identify the hardware operation that bounds the problem.
  2. Reduce the number of those operations per logical operation.
  3. Accept the per-operation cost; it isn't going down.

Step 2 is where mechanical sympathy lives. The cached-indices optimization in modern SPSC queues converts ~3 cache-coherence transactions per push to ~1 per N pushes, a 20× speedup. The FAA-over-CAS insight converts O(log N) coherence round-trips per increment under contention to O(1). flat-combining amortizes a single lock acquisition across N pending operations.

The 125× linked-list result

The cleanest single demonstration of the principle, from Johnny's Software Lab — traversal of 64M doubles through the same logical linked list with three different memory layouts:

Layout Time Speed
Random (naive malloc) 15.0 s 1×
Compact (pool, unordered) 9.7 s 1.5×
Perfect (sequential order) 0.12 s 125×

Identical code, identical algorithm, identical instruction count — the only difference is whether the hardware prefetcher can stream the data. A 99% L3 miss rate becomes ~zero misses. This is mechanical sympathy reduced to its smallest possible expression: the same program runs 125× faster when the data layout matches the access pattern. See fastest-linked-lists for what the field built on top of this finding.

When mechanical sympathy fails

The frame is wrong for two kinds of work:

The frame is right when the algorithm is fixed (you're already using the right queue, the right hash table, the right sort) and the question is how close to the hardware floor you can get.

What this means in practice

For an engineer:

See also

Linked from

Sources