The Memory Hierarchy & Caches

prefetching

A good waiter notices you are halfway through your water and refills it before you ask — so you never have to wait. Prefetching is the cache playing this attentive waiter: it tries to guess which data the program will need soon and fetch it into the cache BEFORE the program actually asks, so that what would have been a slow miss becomes a fast hit by the time the access really happens.

The guessing exploits the same locality that caching does. The simplest and most common is a hardware stream/stride prefetcher: it watches the addresses being accessed, detects a regular pattern (for example, each access is 64 bytes after the last — a unit stride through an array), and speculatively fetches the next line or several lines ahead of the program. Software prefetching is the other form: the compiler or programmer inserts explicit prefetch instructions (hints that say 'please start fetching address X, I'll need it shortly') for patterns the hardware cannot easily spot. Either way, the goal is to overlap the long memory latency with useful computation, so the data has already arrived when it is needed.

Prefetching is most effective for predictable, sequential access (streaming through arrays) and is one reason a forward array scan can run near memory-bandwidth speed despite the underlying latency. But it is a speculative bet, and the honesty matters: a wrong guess wastes memory bandwidth fetching data that is never used, and can even evict useful data to make room (cache pollution), so an overly aggressive prefetcher can make things slower. It also cannot help truly irregular, data-dependent access — chasing scattered pointers, where the next address is unknown until the current load completes, defeats stride prediction. Prefetching attacks compulsory misses by pulling data in before its first use, but it amplifies good locality rather than creating it from nothing.

Summing a million-element array, a stride prefetcher sees the unit-stride pattern and fetches lines ahead of the loop, so each line is already in cache when reached — the loop runs near memory bandwidth. The same prefetcher does nothing for a linked-list walk, where each next address is unknown until the current node loads.

Fetch data before it is asked for, turning a future miss into a hit — great for predictable strides.

Prefetching is a speculative bet that can backfire: wrong guesses waste bandwidth and can pollute the cache by evicting useful data, making code slower. And it cannot rescue irregular, pointer-chasing access where the next address is unknown until the current load returns.

Also called
prefetch預先擷取