0 · The machine from the top Draft
Measurement and the toolbox
On this page
0.11 Measuring latency
Latency is how long one thing takes, from a defined start to a defined end: packet arrival to order departure, say. Throughput is how many things complete per second. A system can have high throughput and poor latency, and a trading system cares about latency, one message at a time.
Measure many of them and you have a distribution, and the right way to describe it is by percentiles. The p50, the median, is the value half the measurements fall below; the p99 is the value 99% fall below; the max is the worst one seen. The slow end, above the p99, is the tail. A mean hides it: a thousand messages at 1 µs and one at 1 ms average to 2 µs, a number nothing actually took, while the one slow message is the one that missed a trade. Every lab in the book reports p50, p99 and max and never a mean.
A histogram is how you keep a distribution without storing every sample: count how many measurements fell into each bucket. Buckets spaced on a log scale (1–2 µs, 2–4, 4–8, …) cover microseconds to seconds in a few dozen counters, and hdrhistogram offers configurable precision over a preallocated range. Disable automatic resizing and handle out-of-range samples explicitly to keep recording allocation-free.
The traps are in the setup. The first pass through any code is slow for reasons that have nothing to do with the code: page faults, cold caches, an untrained branch predictor; warm up before timing. A core’s clock speed changes with load and temperature, so pin the governor. The OS can pause your thread mid-measurement, so pin the thread and measure on an isolated core. Reading a clock costs 20–30 ns, so do not time things that take 4. And when a benchmark stops generating requests while waiting for a reply, it omits the requests that would have arrived during the stall; Gil Tene calls this coordinated omission and Chapter 7 explains the fix.
Two tools do most of the work. perf stat reads the CPU’s hardware counters over a whole run: cycles, instructions, cache misses, branch mispredicts; instructions per cycle (IPC) is the first number to look at, high for compute-bound code and low for memory-bound. perf record samples where the core was every few thousand cycles, and a flame graph draws those samples as a stack of boxes, wider for functions that took more time. Together they say how fast, and where the time went; the predict-first rule says what you expected before you looked.
0.12 The toolbox
Every tool the labs use, what it shows, and the chapter where it is used. Install them before Chapter 1: perf comes with linux-tools, numactl, strace and tcpdump from the distribution, cargo-show-asm as a Cargo-installed tool, and hdrhistogram as a dependency of the lab programs.
| Tool | What it shows | Chapter |
|---|---|---|
lscpu, /sys/devices/system/cpu | Cores, sockets, cache sizes and ways, hyperthread siblings | Chapter 1 |
perf stat -e cycles,instructions,cache-misses,branch-misses | Hardware counters over a run: IPC, misses, mispredicts | Chapter 1 |
perf c2c | Which cache lines bounce between cores (false sharing) | Chapter 1 |
taskset -c N, sched_setaffinity | Pin a process or thread to core N | Chapter 1 |
cpupower frequency-set -g performance | Request a performance policy; record actual frequency and turbo behaviour | Chapter 1 |
numactl --hardware, numactl --cpunodebind --membind | Socket layout; run on one socket with its own memory | Chapter 1 |
cargo asm (cargo-show-asm), objdump -d | The machine instructions the compiler produced | Chapter 1 |
strace -c, perf trace | Which syscalls a program made, and how many | Chapter 2 |
isolcpus, nohz_full, IRQ affinity | Kernel boot options that keep a core quiet | Chapter 2 |
rdtsc | The reference-tick counter on x86; calibrate and order reads for timing | Chapter 2 |
loom | Explores modelled interleavings within configured bounds; has memory-model limitations | Chapter 3 |
tcpdump, Wireshark | Capture and read packets on the wire | Chapter 4 |
ss -i, /proc/net | Socket state, TCP options, queue sizes | Chapter 4 |
criterion | Rust micro-benchmarks with statistics and warm-up | Chapter 5 |
hdrhistogram | Fixed-size latency histograms with percentiles | Chapter 7 |
perf record + flame graph | Where the time went, by function | Chapter 7 |
Further reading
- Randal Bryant and David O’Hallaron, Computer Systems: A Programmer’s Perspective: chapters 1, 3, 6, 9 and 11 cover sections 0.1–0.7 of this chapter properly.
- David Patterson and John Hennessy, Computer Organization and Design, chapters 1–5, for the instruction cycle and the pipeline from first principles.
- Nand2Tetris, a free course that builds a CPU from logic gates; the first six projects make section 0.3 concrete.
- Beej’s Guide to Network Programming, the Chapter 4 reading, for sockets and the TCP/UDP calls in practice.
- The Wikipedia articles on the instruction cycle, von Neumann architecture, cache lines, system calls and the order book as quick reference.
- Brendan Gregg, Systems Performance, chapter 2, for the measurement vocabulary of section 0.11.