Code walkthrough

Translation prefetching
using page-table-embedded deltas
(or just put them on the side)

TRAIL

TRAIL augments each translation with the ones that most often follow it — so fetching a translation during a page-table walk also delivers the next prediction, and the walker can run ahead down the successor chain. These notes walk the implementation in Virtuoso; the class is TemporalPTEPrefetcher (“TRAIL” is the paper name).

class TemporalPTEPrefetcher key temporal_pte Sniper + MimicOS baseline asp
demand VPNn walk PTE payload · 4 slots Δ1 Δ2 Δ3 Δ4 VPN+Δ +Δ' run-ahead along the successor chain
Spare page-table bits hold deltas to a region's usual successors; each prediction can be followed one step further.
1 / 5

Orientation

Where the code lives

The mechanism is one prefetcher class plus a bit-packing codec; the TLB and page table provide the storage and the install path. All paths are under simulator/sniper/…/parametric_dram_directory_msi/.

FileRole
TemporalPTEPrefetcher.{h,cc}the prefetcher — learning (learnTransition) and issue (performPrefetch)
tlb_prefetching/pte_offset_codec.hpacks/unpacks the delta+confidence slots inside a payload word
page_tables/payload_word.hthe 256-bit PayloadWord that rides with a translation
page_tables/pagetable.hread/writePayloadBits — where the payload is stored
tlb_prefetching/tlb_prefetcher_base.{h,cc}prefetcher interface + PTWTransparent (a walk that doesn't move the clock)
tlb.ccthe prefetch queue — enqueue, dedup, and materialize into the L2 TLB
tlb_prefetching/tlb_prefetcher_factory.hconfig → object; dispatch on "temporal_pte"
mmu_configs/mmu_temporal_pte.cfgthe knobs (slots, widths, region size, depth, PQ size)

The mechanism · miss → learn → predict → install → hit

The implementation, stage by stage

1

The payload: successors packed into spare bits

A region's payload is a set of k slots, each a signed delta-VPN (in region units) plus a small confidence counter. The production layout is 4 slots of an 18-bit delta and a 2-bit counter — 80 bits, sized to the spare bits across one page-table cache line.

The payload is a PayloadWord (256 bits) that travels with a translation and is read/written through the page table via readPayloadBits / writePayloadBits.

2

Learning: the table writes successors into the predecessor

On a transition src → curr, TRAIL computes the signed delta and updates the source region's payload — bumping a matching slot or evicting the lowest-confidence one — then writes it back into the page table. Next time that predecessor is walked, the successor is already there.

3

Reading the payload prefetches the next one

On the walk, TRAIL decodes the demand region's slots and, for each confident delta, issues a transparent walk for region + Δ. Crucially, the predicted region's payload is enqueued at depth+1 — so TRAIL follows the successor of the successor, running ahead down the chain up to max_prefetch_depth.

Each transparent walk (PTWTransparent) restores the caller's clock, so demand-path timing is never charged for a prediction.

4

Predictions land in the L2 TLB via a prefetch queue

Each prediction returns with a completion timestamp and waits in a timestamp-ordered queue (capped at the PQ size). When the demand clock passes that time, the entry is allocated into the L2 TLB, tagged as a prefetch, and the prefetcher is told its guess is now resident.

A later demand for that region hits the installed entry — a pq_hit — and skips the walk entirely. That saved walk is the payoff.

5

Two homes for the payload

The successors can ride in the spare bits of the PTE (v4-trail), or live in a separate OS-managed radix side-car table (v4-trail-sidecar) fetched in parallel with the walk. The side-car never slows translation — it only shifts when a prediction becomes available.

v4-trail

In-PTE payload

Rides in spare page-table bits, read inline during the walk. No extra structure; bounded by the ~80-bit spare-bit budget.

v4-trail-sidecar

OS radix side-car

Payload in a separate table with its own walk cache, fetched in parallel. Frees the PTE and widens the budget, at the cost of a parallel lookup.

Configuration

What the config sets

The mechanism is a handful of parameters in config/mmu_configs/mmu_temporal_pte.cfg (per-experiment overrides in clist_prefetcher_v3.yaml). The ones that matter:

KeyValueMeaning
num_offsets4successor slots per translation
offset_bits18signed Δ width — ±128K regions
conf_bits2confidence counter per slot
region_shift3 – 5pages per region (32KB → 128KB); also the fan-out
max_prefetch_depth1 – 3how far to run ahead on the chain
pq1/size1024prefetch-queue capacity
modepc_cond_learnlearn transitions per program counter
Note. region_shift does double duty: it sets both the prediction granularity and the fan-out — one prediction installs 2^region_shift TLB entries, but is charged only one modeled walk per PTE cache line.

Evaluation

Measured effect

Single-core numbers are geometric means over the workload suite; the multi-core number is an equal-work harmonic mean across the four cores. Perfect-L2TLB is an idealized upper bound. All figures reproduce from the public artifact.

Configurationvs no-prefetchvs best priorPerfect-L2TLB
Single-core, 8 MB LLC+4.7%+2.4%+11%
Single-core, 2 MB LLC+5.1%+2.8%+16.5%
4-core, mixed (hmean)+11%≈+6pt+23%

“Best prior” is the strongest of ASP, Stride/NextPage, DP, Recency, ATP, and Berti on that configuration. Reproduce everything from the artifact.