Readings for Next Two Lectures ‣ Text CPSC 213 •Physical and Virtual Addressing - Address Spaces, Page Tables - Page Faults •2nd edition: 9.1-9.2, 9.3.2-9.3.4 •1st edition: 10.1-10.2, 10.3.2-10.3.4 Introduction to Computer Systems Unit 2d Virtual Memory 1 2 Multiple Concurrent Program Executions Virtual Memory ‣ So far we have ‣ Virtual Address Space • an abstraction of the physical address space of main (i.e., physical ) memory • a single program • programs access memory using virtual addresses • multiple threads ‣ Allowing threads from different program executions • hardware translates virtual address to physical memory addresses ‣ Process • we often have more than one thing we want to do at once(ish) • a program execution with a private virtual address space • threads spend a lot of time blocked, allowing other threads to run • associated with authenticated user for access control & resource accounting • but, often there aren’t enough threads in one program to fill all the gaps ‣ What is a program execution • running a program with 1 or more threads ‣ MMU • an instance of a program running with its own state stored in memory • memory management unit • compiler-assigned addresses for all static memory state (globals, code etc.) • the hardware that translates virtual address to physical address • security and failure semantics suggest memory isolation for each execution • performs this translation on every memory access by program ‣ But, we have a problem • there is only one memory shared by all programs ... 3 4
Implementing the MMU Implementing Address Translation ‣ Let’s think of this in the simulator ... class MMU extends MainMemory { byte [] physicalMemory; •introduce a class to simulate the MMU hardware AddressSpace currentAddressSpace; void setAddressSpace (AddressSpace* as); class MMU extends MainMemory { byte [] physicalMemory; byte readByte (int va) { AddressSpace currentAddressSpace; int pa = currentAddressSpace.translate (va); return physicalMemory.read (pa); void setAddressSpace (AddressSpace* as); } } byte readByte (int va) { int pa = currentAddressSpace.translate (va); return physicalMemory.read (pa); } } ‣ Goal •translate any virtual address to a unique physical address (or none) •currentAddressSpace is a hardware register •fast and efficient hardware implementation •the address space performs virtual-to-physical address translation ‣ Let’s look at a couple of alternatives ... 5 6 Base and Bounds But, Address Space Use May Be Sparse ‣ An address space is ‣ Issue • the address space of a program execution is divided into regions •a single, variable-size, non-expandable chunk of physical memory • for example: code, globals, heap, shared-libraries and stack •named by its base physical address and its length 0 0 • there are large gaps of unused address space between these regions ‣ As a class in the simulator 0 0 ‣ Problem class AddressSpace { • a single base-and-bounds mapping from virtual to physical addresses int baseVA, basePA, bounds; L • means that gaps in virtual address space will waste physical memory L int translate (int va) { 0 • this is the Internal Fragmentation problem int offset = va - baseVA; if (offset < 0 || offset > bounds) M throw new IllegalAddressException (); return basePA + offset; Wasted } 0 Physical } Memory ‣ Problems N ‣ Solution P P 7 8
Segmentation But, Memory Use Not Known Statically ‣ An address space is ‣ Issue • a set of segments • segments are not expandable ; their size is static ‣ A segment is • some segments such as stack and heap change size dynamically • a single, variable-size, non-expandable chunk of physical memory ‣ Problem • named by its base virtual address, physical address and length • segment size is chosen when segment is created ‣ Implementation in Simulator • too large and internal fragmentation wastes memory class AddressSpace { • too small and stack or heap restricted Segment segment[]; int translate (int va) { for (int i=0; i<segments.length; i++) { int offset = va - segment[i].baseVA; Wasted if (offset >= 0 && offset < segment[i].bounds) { OR pa = segment[i].basePA + offset; Physical Broken return pa; Memory Program } } throw new IllegalAddressException (va); }} ‣ Solution ‣ Problem • allow segments to expand? 9 10 But, There May Be No Room to Expand But, Moving Segments is Expensive ‣ Issue ‣ Issue • segments are contiguous chunks of physical memory • if there is space in memory to store expanding segment, but not where it is • a segment can only expand to fill space between it and the next segment • could move expanding segment or other segments to make room ‣ Problem • external fragmentation is resolved by moving things to consolidate free space ‣ Problem • there is no guarantee there will be room to expand a segment • the available memory space is not where we want it (i.e., adjacent to segment) • moving is possible, but expensive • to move a segment, all of its data must be copied • this is the External Fragmentation problem • segments are large and memory copying is expensive Maybe But, Now Some We’re Move Room to Maybe Other Stuck Some Expand Segments Room to to Make Expand Room ‣ Solution 11 12
Expand Segments by Adding Segments Eliminating External Fragmentation ‣ What we know ‣ The problem with what we are doing is • allocating variable size segments leads to external fragmentation of memory • segments should be non-expandable • this is an inherent problem with variable-size allocation • size can not be effectively determined statically ‣ What about fixed sized allocation ‣ Idea • could we make every segment the same size? • instead of expanding a segment • this eliminates external fragmentation • make a new one that is adjacent virtually, but not physically • but, if we make segments too big, we’ll get internal fragmentation • so, they need to be fairly small and so we’ll have lots of them virtual addresses m ... n-1 Allocate a New Segment virtual addresses n ... p-1 ‣ Problem ‣ Problem • oh no! another problem! what is it? why does it occur? 13 14 Translation with Many Segments Paging ‣ What is wrong with this approach if there are many segments? ‣ Key Idea • Address Space is divided into set of fixed-size segments called pages class AddressSpace { • number pages in virtual address order Segment segment[]; • page number = virtual address / page size int translate (int va) { ‣ Page Table for (int i=0; i<segments.length; i++) { int offset = va - segment[i].baseVA; • indexed by virtual page number (vpn) if (offset > 0 && offset < segment[i].bounds) { pa = segment[i].basePA + offset; • stores base physical address (actually address / page size (pfn) to save space) return pa; } • stores valid flag , because some segment numbers may be unused } throw new IllegalAddressException (va); }} ‣ Now what? • is there another way to locate the segment, when segments are fixed size? 15 16
‣ New terminology ‣ The bit-shifty version • page a small, fixed-sized (4-KB) segment •assume that page size is 4-KB = 4096 = 2 12 • page table virtual-to-physical translation table •assume addresses are 32 bits • pte page table entry •then, vpn and pfn are 20 bits and offset is 12 bits • vpn virtual page number •pte is pfn plus valid bit, so 21 bits or so, say 4 bytes • pfn physical page frame number •page table has 2 20 pte’s and so is 4-MB in size • offset byte offset of address from beginning of page ‣ Translation using a Page Table ‣ The simulator code class PageTableEntry { class AddressSpace { class PageTableEntry { boolean isValid; class AddressSpace { PageTableEntry pte[]; boolean isValid; int pfn; PageTableEntry pte[]; int pfn; } int translate (int va) { } int translate (int va) { int vpn = va / PAGE_SIZE; int vpn = va >>> 12; int offset = va % PAGE_SIZE; int offset = va & 0xfff; if (pte[vpn].isValid) if (pte[vpn].isValid) return pte[vpn].pfn * PAGE_SIZE + offset; return pte[vpn].pfn << 12 | offset; else else throw new IllegalAddressException (va); throw new IllegalAddressException (va); }} }} 17 18 The MMU Hardware Context Switch ‣ Translation performance ‣ A context switch is • switching between threads from different processes •translation occurs on every memory reference • each process has a private address space and thus its own page table •so it must be very fast most of the time ‣ Implementing a context switch ‣ TLB • change PTBR to point to new process’s page table •translation lookaside buffer • invalidate stale TLB entries (may require flushing entire TLB) •a cache that is fast to access and where recent translations are stored • switch threads (save regs, switch stacks, restore regs) ‣ TLB Miss ‣ Context Switch vs Thread Switch •requires a page table lookup • changing page tables can be considerably slower than just changing threads •page-table-base register (PTBR) stores address of page table • mainly because of TLB •think of page table as being in physical memory • new process has no valid TLB entries and thus suffers many TLB misses - page table is actually paged, but in a different way than the address space •lookup could be done in hardware (IA32) or software (IA64 option) 19 20
Recommend
More recommend