liveBook · Manning

CPU cache

As explained in Fast Python: High performance techniques for large datasets

A CPU cache is small, fast memory that stores copies of data or instructions for quicker access by a processor.

CPU caches sit between processor registers and main memory. A cache hit lets the processor use data without waiting for slower RAM; a miss can leave it idle while data is fetched. Cache capacity is limited, so the speed of a computation depends not just on its arithmetic but on which data it accesses and in what order. section 6.1.2

Table 6.1 Memory hierarchy with sizes and access times for a hypothetical, but realistic modern desktop (view table figure)

Type

Size

Access time

CPU

L1 cache

256 KB

2 ns

L2 cache

1 MB

5 ns

L3 cache

6 MB

30 ns

RAM

DIMM

8 GB

100 ns

Compare the illustrative capacities and access times of L1, L2, and L3 caches with RAM. The orders of magnitude matter more than the particular machine's numbers. section 6.1.2

Measure a NumPy access pattern

Create a square NumPy array, then time `2 * mat[:, 0]` and `2 * mat[0, :]` as its size grows. In one 10,000-by-10,000 test, doubling a column took 4.51 µs versus 74.9 µs for a row. The result is not a rule that columns are faster: the array's internal representation and the relationship between cache and main memory determine the difference. section 6.1.1 section 6.1.2

Accessing one matrix element can bring nearby elements into cache. Operations on contiguous elements may therefore reuse one memory transfer, while operations on separated elements may require a transfer for each access. Small arrays can conceal this cost; large arrays can make it dominant. Whether rows or columns are contiguous depends on the matrix representation. section 6.1.2

This also explains why extra computation is not always slower. A compressed block that fits in cache can sometimes be processed faster than raw data that repeatedly waits on RAM, even after accounting for decompression. Measure such gains on the intended machine: other processes can compete for cache, and NumExpr speedups observed on a server may shrink or disappear on a busy laptop. section 1.2.1 section 6.3.2

Table 6.6 The effect of hardware architecture on performance: Speedup as a function of hardware (view table figure)

Expression

Server speedup

Laptop speedup

a + a

3.8

0.7

f + f

3.8

0.8

a + f

3.7

1.3

a**5 + f

19.4

11.5

a**5 + f + sin(a) + cos(a)

25.1

6.7

The same NumExpr expressions show different speedups on a server and a laptop, illustrating why cache-sensitive optimizations need testing on the target hardware. section 6.3.2

How Fast Python: High performance techniques for large datasets covers it

How deep it goes
Works through cache hits, memory transfers, and contiguous matrix access, without detailing cache implementation.
Examples
Times NumPy row and column operations and compares NumExpr speedups on server and laptop hardware.
What it assumes
Assumes familiarity with NumPy array operations while explaining the relevant memory hierarchy and access-pattern effects.
What you can do after
Diagnose/debug cache-sensitive slowdowns by benchmarking array access patterns and retesting optimizations on target hardware.
How it connects
Links CPU cache to RAM latency, memory hierarchy, NumPy array layout, compression, and NumExpr.

Also explained in

Compare how 3 books explain CPU cache →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Fast Python: High performance techniques for large datasets. The section links point to the parts of the book it draws on.