Lecture 6 - Segmentation and Paging
Instructor: Michael Swift Topics: Memory virtualization, segmentation, paging, page tables, TLBs
Learning Outcomes
- Identify main techniques to virtualize memory
- Explain the benefits and shortcomings of each technique
Dynamic Relocation (Recap)
Goal: Protect processes from one another
Requires hardware support
- Memory Management Unit (MMU)
MMU dynamically changes process address at every memory reference
- Process generates logical or virtual addresses (in their address space)
- Memory hardware uses physical or real addresses
graph LR
CPU -->|Logical address| MMU
MMU -->|Physical address| Memory
Lecture Note
The OS can control the MMU. The process runs on the CPU, which sends logical addresses to the MMU, which translates them to physical addresses for memory.
Segmented Addressing
Process now specifies segment and offset within segment.
How does process designate a particular segment?
- Use part of logical address
- Top bits of logical address select segment
- Low bits of logical address select offset within segment
What if small address space, not enough bits?
- Implicitly by type of memory reference
- Special registers
Practice: Segment Translation
Example
2-bit segments, 12-bit offsets. Translate logical (hex) to physical.
| Segment | Base | Bounds | R W |
|---|---|---|---|
| 0 | 0x2000 | 0x6ff | 1 0 |
| 1 | 0x0000 | 0x4ff | 1 1 |
| 2 | 0x3000 | 0xfff | 1 1 |
| 3 | 0x0000 | 0x000 | 0 0 |
Remember: 1 hex digit = 4 bits
Lecture Note
- 0x0240: top 2 bits = segment 0, offset = 0x240. Physical = 0x2000 + 0x240 = 0x2240
- 0x1108: segment 1, offset = 0x108. Physical = 0x0000 + 0x108 = 0x0108
- 0x265c: segment 2, offset = 0x65c. Physical = 0x3000 + 0x65c = 0x365C. Also noted as 0x397C (checking bounds)
- 0x3002: segment 3, R/W = 0 0 — invalid (segment not allocated)
How Do Stacks Grow?
Stack goes from high addresses to low addresses (e.g., 16K down to 12K in virtual, 28K down to 24K in physical).
- Segment base is at 28K; size is 4K
Example: Virtual address 0x3C00 = 15K
- Top 2 bits (0x3) = segment reference, offset is 0xC00 = 3K
- How do we make CPU translate that?
Solution: Add a “grows down” bit to segment. Calculate negative offset from top.
Lecture Note
Negative offset = subtract segment size from offset = 3K (offset) - 4K (size) = -1K from top Add to base = 28K - 1K = 27K; 0x3C00 maps to 27K physical
Advantages of Segmentation
Enables sparse allocation of address space
- Stack and heap can grow independently
- Heap: If no data on free list, dynamic memory allocator requests more from OS (e.g., UNIX:
malloccallssbrk()) - Stack: OS recognizes reference outside legal segment, extends stack implicitly
- Segment table stored in CPU; no extra memory references for translation
Different protection for different segments
- Enables sharing of selected segments
- Read-only status for code
Supports dynamic relocation of each segment
Lecture Note
Two processes can share a code segment (read-only) while having separate heap and stack segments.
Disadvantages of Segmentation
Each segment must be allocated contiguously
May not have sufficient physical memory for large segments
External fragmentation — free memory is split into small, non-contiguous chunks
Lecture Note
Solution is relocation/compaction, but it’s slow. Physical memory diagram shows “not in use” gaps between allocated segments.
Practice: Relocation Techniques
| Description | Segmentation | Static Relocation | Base | Base+Bounds | Time Sharing |
|---|---|---|---|---|---|
| Add per-process starting location to virt addr to obtain phys addr | Yes | Yes | |||
| Rewrite code and addresses before running | Yes | ||||
| Several base+bound pairs per process | Yes | ||||
| One process uses RAM at a time | Yes | ||||
| Dynamic approach that verifies address is in valid range | Yes | Yes |
Paging
Goal: Eliminate requirement that address space is contiguous
- Eliminate external fragmentation
- Grow segments as needed
Idea: Divide address spaces and physical memory into fixed-sized pages
- Size: 2^n, Example: 4KB
- Like lots of fixed-size segments
Lecture Note
Small pages from each process map to arbitrary physical frames. Multiple processes’ pages are interleaved in physical memory.
Translation of Page Addresses
How to translate logical address to physical address?
- High-order bits of address designate virtual page number (VPN)
- Low-order bits of address designate offset within page
For a 32-bit address with 4KB pages:
- 20 bits = page number (VPN)
- 12 bits = page offset
The VPN is translated to a physical frame number (PFN). The offset is appended unchanged.
No addition needed; just append bits correctly!
Lecture Note
The page number is also called the “virtual page number.” The frame number is the “physical page number.”
Address Format
Given known page size, how many bits are needed for offset?
| Page Size | Low Bits (offset) |
|---|---|
| 16 bytes | 4 |
| 1 KB | 10 |
| 1 MB | 20 |
| 512 bytes | 9 |
| 4 KB | 12 |
Lecture Note
Offset bits = log2(page size)
Given number of bits in virtual address and bits for offset, how many bits for VPN?
| Page Size | Low Bits (offset) | Virt Addr Total Bits | High Bits (VPN) |
|---|---|---|---|
| 16 bytes | 4 | 10 | 6 |
| 1 KB | 10 | 20 | 10 |
| 1 MB | 20 | 32 | 12 |
| 512 bytes | 9 | 16 | 7 |
| 4 KB | 12 | 32 | 20 |
Given number of bits for VPN, how many virtual pages can there be?
| Page Size | Low Bits (offset) | Virt Addr Bits | High Bits (VPN) | Virt Pages |
|---|---|---|---|---|
| 16 bytes | 4 | 10 | 6 | 64 |
| 1 KB | 10 | 20 | 10 | 1024 |
| 1 MB | 20 | 32 | 12 | 4096 |
| 512 bytes | 9 | 16 | 7 | 128 |
| 4 KB | 12 | 32 | 20 | 1M |
Virtual to Physical Page Mapping
The number of bits in the virtual address need not equal the number of bits in the physical address.
The VPN is translated to a PPN through an address mapper. The offset bits pass through unchanged.
How should OS translate VPN to PPN? Use a page table.
Linear Page Tables
Simple solution: Linear page table (an array)
Entries are Page Table Entries (PTEs):
- Physical page address (page frame number / PFN)
- Permissions
- Extra bits
The array is indexed by VPN, with 2^n entries.
Lecture Note
x86 PTE format (32 bits): upper bits store PFN, lower bits include flags — P (present), R/W (read/write), U/S (user/supervisor), PWT, PCD, A (accessed), D (dirty), PAT, G (global).
Example Translation
Example
Virtual address 0x122: VPN = 0x1, offset = 0x22. Page table maps VPN 1 to PPN 0xB. Physical address = 0xB22.
Per-Process Page Tables
Each process has its own page table, mapping its virtual pages to different physical frames.
Lecture Note
Protection: a process can’t reference a page of another process because each has its own page table. Example: P1’s page table maps VPN 0-3 to PFN 1, 3, 7, 10. P2 maps to 0, 2, 4, 6. P3 maps to 8, 5, 9, 11.
Translation Steps with Paging
For each memory reference:
- Extract VPN (virtual page number) from VA (virtual address)
- Calculate address of PTE (page table entry)
- Read PTE from memory; check present bit
- Extract PFN (page frame number)
- Build PA (physical address)
- Read contents of PA from memory
Example
14-bit addresses, page table at physical address 0x5000, PTEs are 4 bytes, 4KB pages (12-bit offset).
Simplified page table: VPN 0 → PFN 2, VPN 1 → PFN 7, VPN 2 → PFN 80, VPN 3 → PFN 99.
READ 0x1103: VPN = 0x1, offset = 0x103. PTE lookup → PFN 7. Physical address = 0x7103.
Memory Accesses with Pages
0x0010: movl 0x1100, %edi
0x0013: addl $0x3, %edi
0x0019: movl %edi, 0x1100
Assume page table at physical address 0x5000, PTEs are 4 bytes, 4KB pages.
With segmentation: 5 memory references (3 instruction fetches, 2 movl data accesses)
Physical memory accesses with paging:
- Fetch instruction at logical address
0x0010(VPN 0)- Access page table: mem ref 1 →
0x5000 - Learn VPN 0 is at PPN 2
- Fetch instruction at
0x2010(mem ref 2)
- Access page table: mem ref 1 →
- Execute load from logical address
0x1100(VPN 1)- Access page table: mem ref 3 →
0x5004 - Learn VPN 1 is at PPN 0
movlfrom0x0100into register (mem ref 4)
- Access page table: mem ref 3 →
Key Insight
Page table is slow — it doubles memory references. Every data/instruction access requires an extra access to the page table.
Practice: Page Tables
Consider a 32-bit address space with 4 KB pages. Assume each PTE is 4 bytes.
- How many bits to represent the offset within a page?
- log2(4KB) = 12 bits
- How many virtual pages?
- 2^(32-12) = 2^20 = 1M pages
- What is the overall size of the page table?
- 4 bytes x 1M = 4 MB
Page Size Tradeoffs
How big should pages be?
Small pages:
- Large page tables
Large pages:
- Internal fragmentation — extra space allocated but not used
Advantages of Paging
- No external fragmentation — any page can be placed in any frame in physical memory
- Fast to allocate and free
- Alloc: No searching for suitable free space
- Free: Doesn’t have to coalesce with adjacent free space
- No relocation needed
Disadvantages of Paging
- Additional memory reference to page table → very inefficient
- Page table must be stored in memory
- MMU stores only base address of page table
- Storage for page tables may be substantial
- Simple page table: requires PTE for all pages in address space
- Entry needed even if page not allocated
- Internal fragmentation
Example: Array Iterator
int sum = 0;
for (i=0; i<N; i++){
sum += a[i];
}
Assume a starts at 0x1000. Ignore instruction fetches and access to i.
Page table entry at address 0x0004 with PFN 0x5.
| Virtual Address | Physical Addresses |
|---|---|
| load 0x1000 | load 0x0004, load 0x5000 |
| load 0x1004 | load 0x0004, load 0x5004 |
| load 0x1008 | load 0x0004, load 0x5008 |
Key Insight
Every array access requires two physical memory accesses: one to read the page table entry, one to read the actual data. This motivates caching translations.
Translation Lookaside Buffer (TLB)
Strategy: Cache page translations in the CPU to avoid repeated page table lookups.
The TLB is a small, fast cache inside the CPU that stores recent VPN → PPN translations.
TLB Organization
Each TLB entry contains:
| Tag (virtual page number) | Physical page number (page table entry) |
Lecture Note
TLB entries also store permissions and a valid bit.
TLB Accesses: Sequential Example
int sum = 0;
for (i = 0; i < 2048; i++){
sum += a[i];
}
Assume a starts at 0x1000, page table entry at address 0x0004 with PFN 0x5, 4KB pages.
Virtual address stream: load 0x1000, load 0x1004, load 0x1008, load 0x100C, …
Example
Setup: Page table at physical address pointed to by PTBR. P1 page table: VPN 0 → PFN 1, VPN 1 → PFN 5, VPN 2 → PFN 4, …
- load 0x1000 (VPN 1): TLB miss → read PTE at 0x0004, get PPN 5, load from 0x5000. TLB now has {VPN 1 → PPN 5}.
- load 0x1004 (VPN 1): TLB hit → load from 0x5004
- load 0x1008 (VPN 1): TLB hit → load from 0x5008
- load 0x100C (VPN 1): TLB hit → load from 0x500C
- … (all hits until crossing page boundary)
- load 0x2000 (VPN 2): TLB miss → read PTE at 0x0008, get PPN 4, load from 0x4000. TLB now also has {VPN 2 → PPN 4}.
- load 0x2004 (VPN 2): TLB hit → load from 0x4004
TLB Performance
Miss rate of TLB: # TLB misses / # TLB lookups
int sum = 0;
for (i=0; i<2048; i++) {
sum += a[i];
}
Int is 4 bytes. With 4KB pages, each page holds 1024 ints.
- TLB lookups = number of accesses to
a= 2048 - TLB misses = number of unique pages accessed = 2
- Miss rate = 2/2048 = 1/1024
- Hit rate = 2046/2048 ≈ ~1
Lecture Note
Would hit rate get better or worse with smaller pages? Worse — more pages means more misses.
Improving TLB Performance
How can system improve TLB performance (hit rate) given fixed number of TLB entries?
Increase page size — fewer unique translations needed to access same amount of memory.
Example: access 1 MB array
- 4KB pages: 256 TLB misses
- 256KB pages: 4 TLB misses
Intel/AMD x86-64 supports: 4KB, 2MB, and 1GB pages
Workload Access Patterns
Spatial Locality: Future access will be to nearby addresses.
Temporal Locality: Future access will be repeats to the same data.
What TLB characteristics are best for each type?
Spatial:
- Access same page repeatedly; need same VPN → PPN translation
- Same TLB entry re-used
- Larger pages help
Temporal:
- Access same address near in future
- Same TLB entry re-used in near future
- How near in future? How many TLB entries are there?
- More TLB entries help
TLB and Context Switches
What happens if a process uses cached TLB entries from another process?
- Flush TLB on each switch
- Costly → lose all recently cached translations
- Track which entries are for which process
- Address Space Identifier (ASID)
- Tag each TLB entry with an 8-bit ASID
Example: TLB with ASID
P1 page table (ASID 11): VPN 0 → PFN 1, VPN 1 → PFN 5, VPN 2 → PFN 4, … P2 page table (ASID 12): VPN 0 → PFN 6, VPN 1 → PFN 2, VPN 2 → PFN 3, …
Valid Virt Phys ASID 0 1 9 11 1 1 5 11 1 1 2 12 1 0 1 11
load 0x1444with ASID 12 → matches VPN 1, ASID 12 → PPN 2.load 0x1444with ASID 11 → matches VPN 1, ASID 11 → PPN 5.
Context switches are expensive. Even with ASID, other processes “pollute” TLB.
Architectures can have multiple TLBs:
- 1 TLB for data, 1 TLB for instructions
- 1 TLB for regular pages, 1 TLB for “super pages”
HW and OS Roles
CPU must know where page tables are
CR3register on x86- Page table structure fixed and agreed upon between HW and OS
- HW “walks” the page table and fills TLB
What Happens When OS Updates Page Table?
OS must invalidate TLB entries when PTEs change.
Program: OS: TLB:
Load 0x3250000 PTE[0x3250].PPN = 0x2456 PTE[0x3250]=0x2456
Free(0x3250000) PTE[0x3250].val = 0 PTE[0x3250]=0x2456
invlpg 0x3250 PTE[0x3250]=nil
Load 0x3250000 PTE[0x6434].PPN = 0x2456 PTE[0x3250]=0x2456
Key Insight
After the OS frees a page and updates the PTE, it must use
invlpgto invalidate the stale TLB entry. Otherwise the process could still access the old physical page.
TLB Summary
Pages are great, but accessing page tables for every memory access is slow.
Cache recent page translations → TLB
- MMU performs TLB lookup on every memory access
TLB performance depends strongly on workload
- Sequential workloads perform well
- Workloads with temporal locality can perform well
In different systems, hardware or OS handles TLB misses
TLBs increase cost of context switches
- Flush TLB on every context switch
- Add ASID to every TLB entry
Summary
Operating systems virtualize memory to support multiprogramming
- Each process gets its own address space
- Processes are prevented from accessing each other’s memory
Hardware support required for efficient execution
Segmentation can lead to external fragmentation
Paging uses equal-size memory regions and page tables
Related
- Navigation: ← Lecture 5 · Lecture 7 →
- Exam: Midterm 1
- Course: CS 537 Map of Content