Pagingโs extra memory reference โ before every fetch, load, and store โ is prohibitively slow. Time to make the common case fast.
The Crux: How To Speed Up Address Translation
How can we speed up address translation, and generally avoid the extra memory reference that paging seems to require? What hardware support is required? What OS involvement is needed?Help comes from the OSโs old friend, the hardware: a translation-lookaside buffer (TLB) tlb Translation-lookaside buffer: a small, fast, fully-associative cache of VPNโPFN translations inside the MMU, checked before the page table on every reference โ the hardware that 'in a real sense makes virtual memory possible'. defined in ch. 19 โ open in glossary โ part of the MMU, and simply a hardware cache of popular virtual-to-physical translations (a better name would be address-translation cache). On every reference the hardware checks the TLB first; only when the translation is absent does anyone touch the page table. TLBs, in a real sense, make virtual memory possible.
19.1 TLB Basic Algorithm
The hardwareโs control flow (linear page table, hardware-managed TLB โ Figure 19.1):
VPN = (VirtualAddress & VPN_MASK) >> SHIFT
(Success, TlbEntry) = TLB_Lookup(VPN)
if (Success == True) // TLB Hit
if (CanAccess(TlbEntry.ProtectBits) == True)
Offset = VirtualAddress & OFFSET_MASK
PhysAddr = (TlbEntry.PFN << SHIFT) | Offset
Register = AccessMemory(PhysAddr)
else
RaiseException(PROTECTION_FAULT)
else // TLB Miss
PTEAddr = PTBR + (VPN * sizeof(PTE))
PTE = AccessMemory(PTEAddr)
if (PTE.Valid == False)
RaiseException(SEGMENTATION_FAULT)
else if (CanAccess(PTE.ProtectBits) == False)
RaiseException(PROTECTION_FAULT)
else
TLB_Insert(VPN, PTE.PFN, PTE.ProtectBits)
RetryInstruction()
A hit tlb hit The desired translation is already in the TLB: the physical address forms in a few cycles with no page-table access โ the common case everything is designed around. defined in ch. 19 โ open in glossary forms the physical address in a few cycles โ the TLB sits right next to the core. A miss tlb miss The translation is absent: the page table must be consulted (extra memory reference or worse), the TLB updated, and the instruction retried โ the retry then hits. defined in ch. 19 โ open in glossary pays the old price (the page-table access, an extra memory reference or more), installs the translation, and retries the instruction โ which now hits. The premise, as with all caches: misses are rare, hits are the common case.
19.2 Example: Accessing An Array
Ten 4-byte integers at virtual address 100, in an 8-bit address space with 16-byte pages (4-bit VPN, 4-bit offset):
click a region marked โ for details
Now run for (i = 0; i < 10; i++) sum += a[i]; against a cold TLB โ
counting only the array accesses:
virtual address
100
VPN 6 ยท offset 4
MMU: TLB first, page table only on a miss
no access yet โ click a preset (or โถ access)
| TLB slot | VPN | PFN | valid | note |
|---|---|---|---|---|
| 0 | โ | โ | 0 | |
| 1 | โ | โ | 0 | |
| 2 | โ | โ | 0 | |
| 3 | โ | โ | 0 |
The presets are a[0]โฆa[9] (VAs 100โ136). Run them in order: miss, hit, hit, miss, hit, hit, hit, miss, hit, hit โ 70%, from a stone-cold TLB, on data never touched before. Thatโs spatial locality. Now run the ten again WITHOUT resetting: 100% โ temporal locality. Then reset and try any order you like.
miss, hit, hit, miss, hit, hit, hit, miss, hit, hit โ a 70% hit rate on the very first pass, thanks to spatial locality spatial locality After touching address x, nearby addresses are likely next (array streaming, sequential code). defined in ch. 10 โ open in glossary : array elements pack tightly onto pages, so only the first touch of each page misses. Doubling the page size would halve the misses; with realistic 4KB pages, dense array code misses roughly once per thousand accesses. And if the program loops over the array again soon after? Ten hits out of ten โ temporal locality temporal locality Data accessed now is likely accessed again soon (loop variables, instructions). defined in ch. 10 โ open in glossary , the quick re-reference of recently-used items.
Tip: Use Caching When Possible
Caching is one of the most fundamental performance techniques in computer systems โ the common case made fast by exploiting locality, temporal and spatial. So why not build one giant cache and keep everything in it? Physics. A fast cache must be small โ speed-of-light and related constraints see to it โ and any large cache is by definition slow. Weโre stuck with small, fast caches; the art is using them well.Check yourself
1.What exactly is a TLB, and where does it sit in the translation story?
2.Ten sequential accesses to the array (three pages: VPN 06, 07, 08) with a cold TLB. What's the pattern, and why isn't it 0% hits?
3.Walk the TLB-miss path in the hardware-managed algorithm (Figure 19.1).
4.Two knobs improve the array loop's TLB behavior further: bigger pages, and running the loop again soon. Why does each help?
5.If caches are so effective, why not build one big enough to hold all translations (or all data) and be done?