Virtual Memory (Computer Operating System)
Virtual Memory (Computer Operating System)
Virtual memory is so important that its acronym, i.e., vm, was incorporated into
the name of the Linux kernel as it is used on most systems, i.e., vmlinux for the
non-compressed version and vmlinuz for the compressed, bootable (i.e., runnable)
version.
Recall: memory allocation with variable partitions requires mapping
logical addresses to physical addresses
Virtual memory achieves a complete separation of logical and physical
address-spaces
Today, typically a virtual address is 32 bits, this allows a process to have
4GB of virtual memory
Physical memory is much smaller than this, and varies from machine to
machine
Virtual address spaces of different processes are distinct
Structuring of virtual memory
Paging: Divide the address space into fixed-size pages
Segmentation: Divide the address space into variable-size segments
(corresponding to logical units)
Memory paging is a memory management technique for controlling how a
computer or virtual machine's (VM's) memory resources are shared. A computer
can address memory beyond the amount physically installed on the system. ...
The portion of the hard disk that acts as physical memory is called a page file.
Paging (1)
Paging
Physical memory is divided into chunks called page-frames (on Pentium,
each page-frame is 4KB).
Virtual memory is divided into chunks called pages; size of a page is equal
to size of a page frame
So typically, 220 pages (a little over a million) in virtual memory
OS keeps track of mapping of pages to page-frames
Some calculations:
1. 10-bit address : 1KB of memory; 1024 addresses
2. 20-bit address : 1MB of memory; about a million addresses
3. 30-bit address : 1 GB of memory; about a billion addresses
Paging (2):
The Relation between virtual addresses and physical memory addresses given by
page Table:
It allows us to run more applications on the system than we have enough physical
memory to support. Virtual memory is simulated memory that is written to a
file on the hard drive. That file is often called page file or swap file. It's used by
operating systems to simulate physical RAM by using hard disk space.
Design Issues:
In a operating systems that use paging for memory management, page
replacement algorithm are needed to decide which page needed to be replaced
when new page comes in. Whenever a new page is referred and not present in
memory, page fault occurs and Operating System replaces one of the existing
pages with newly needed page. Different page replacement algorithms suggest
different ways to decide which page to replace. The target for all algorithms is to
reduce number of page faults.
1. What is the “optimal” size of a page frame ?
Now for the further page reference string —> 0 Page fault because they are
already available in the memory.
UMERA ANJUM COMPUTER OPERATING SYSTEMS 8
VIRTUAL MEMORY (REVISED VERSION)
Paging in LINUX:
Linux Uses 3 Level Page Tables. Figure.shows the model, which defines three
types of paging tables.
o Page Global Directory
o Page Middle Directory
o Page Table
Linux uses demand paging to load executable images into a process's virtual
memory. Whenever a command is executed, the file containing it is opened and
its contents are mapped into the process's virtual memory.
The Page Global Directory includes the addresses of several Page Middle
Directories, which in turn include the addresses of several Page Tables. Each
Page Table entry points to a page frame. The linear address is thus split into four
parts. Figure.does not show the bit numbers because the size of each part depends
on the computer architecture.
Linux’s handling of processes relies heavily on paging. In fact, the automatic
translation of linear addresses into physical ones makes the following design
objectives feasible:
o Assign a different physical address space to each process, ensuring an
efficient protection against addressing errors.
o Distinguish pages (groups of data) from page frames (physical addresses
in main memory). This allows the same page to be stored in a page frame,
then saved to disk and later reloaded in a different page frame. This is the
basic ingredient of the virtual memory mechanism
At this point, TLB is checked for a quick reference to the location in physical
memory.
When an address is searched in the TLB and not found, the physical memory
must be searched with a memory page crawl operation. As virtual memory
addresses are translated, values referenced are added to TLB. When a value can
be retrieved from TLB, speed is enhanced because the memory address is stored
in the TLB on processor. Most processors include TLBs to increase the speed of
virtual memory operations through the inherent latency-reducing proximity as
well as the high-running frequencies of current CPU’s.
TLBs also add the support required for multi-user computers to keep memory
separate, by having a user and a supervisor mode as well as using permissions on
read and write bits to enable sharing.
TLBs can suffer performance issues from multitasking and code errors. This
performance degradation is called a cache thrash. Cache thrash is caused by an
ongoing computer activity that fails to progress due to excessive use of resources
or conflicts in the caching system.
Page-tables are in main memory
Access to main memory is slow compared to clock cycle on CPU (10ns
vs 1 ns)
An instruction such as MOVE REG, ADDR has to decode ADDR
and thus go through page tables
This is way too slow !!
Standard practice: Use TLB stored on CPU to map pages to page-frames
TLB stores small number (say, 64) of page-table entries to avoid the
usual page-table lookup
TLB is associative memory and contains, basically, pairs of the form
(page-no, page-frame)
Special hardware compares incoming page-no in parallel with all
entries in TLB to retrieve page-frame
If no match found in TLB, standard look-up invoked
Key design issue: how to improve hit rate for TLB?
Which pages should be in TLB: most recently accessed
Who should update TLB?
Steps in Paging:
Today’s typical systems use TLBs and multi-level paging
Paging requires special hardware support
Overview of steps
1. Input to MMU: virtual address = (page p, offset o)
2. Check if there is a frame f with (p,f) in TLB
Reference String:
Def: The virtual space of a process consists of N = {1,2,…,n} pages.
w = r1 r2 … rk … rT
where rk ∈ N is the page referenced on the kth memory reference.
E.g., N = {0,...,5}.
w=003455522212221100
Clock Algorithm:
Optimization of Second chance
Keep a circular list with current pointer
If current page has R=0 then replace, else set R to 0 and move current
pointer
Belady’s Anomaly:
For FIFO algorithm, as the following counter-example shows,
increasing m from 3 to 4 increases faults
Stack Algorithms:
Thrashing:
Not really! It increases for a while, and then starts dropping again.
Reason: With many processes around, each one has only a few pages
in memory, so more frequent page faults, more I/O wait, less CPU
utilization
Locality Of Reference:
Memory accesses by a program are not spread all over its virtual
memory randomly, but show a pattern
E.g. while executing a procedure, a program is accessing the page that
contains the code of the procedure, the local variables, and global vars
This is called locality of reference
How to exploit locality?
Pre-paging: when a process is brought into memory by the swapper, a few
pages are loaded in a priori (note: demand paging means that a page is
brought in only when needed)
Working set: Try to keep currently used pages in memory
Locality:
The working set of a process is the set of all pages accessed by the
process within some fixed time window.
Locality of reference means that a process's working set is usually small
compared to the total number of pages it possesses.
Ex. h=4
WSClock Algorithm:
Maintain Time of last use for each page (age=virtual time – this field)
If R = 0 and Age > Working set window k and M = 0 then add this
page to
and repeat
If some write has been scheduled then keep advancing current till
some
write is completed
If no write has been scheduled then all pages are in working set so
pick a
Front hand clears R bits and schedules disk writes (if needed)
memory. Sometimes ready processes are swapped out (but not until
they've been in memory for at least 2 seconds).
int a[128][128]
a[i,j]=0
a[i,j]=0
Page Size:
If the avg program size s0 is much larger than the page size z, then the
optimal page size z0 is approximately √2cs0 where c = c1 /c2.
Proof.
c1=c2=1
Z S0 f=Z/S0× 100%
8 32 25
16 128 13
32 512 6
64 2K 3
128 8K 1.6
256 32K .8
512 128K .4
1024 512K .2
c1 > c2⇒ larger page than above (need cache) c1 < c2 (unlikely)
⇒smaller
IBM/370 2K & 4K
VAX 512bytes
Sharing of Pages:
Solution in PDP-11:
In most versions of Unix, upon fork, parent and child use same pages
but have different page table entries
Segmentation:
Advantages:
Application specific
Two examples
Multics
Pentium
Multics Memory
34-bit address split into 18-bit segment no, and 16 bit (virtual) address
within the segment
Address within segment is divided into 6-bit page number and 10-bit
offset
Each segment entry points to page table that contains upto 64 entries
main memory address of page table (but only 18 bits needed, last
6 bits assumed to be 0)
Length of segment (in terms of number of pages, this can be used
for a limit check)
Protection bits
More details
Memory access first has to deal with segment table and then with
page table before getting the frame
Pentium:
Limit check
Add Offset to base address of segment
In many ways, the virtual memory on the Pentium resembles that of MULTICS,
including the presence of both segmentation and paging. Whereas MULTICS has
256K independent segments, each up to 64K 36-bit words, the Pentium has 16K
independent segments, each holding up to 1 billion 32-bit words. Although there
are fewer segments, the larger segment size is far more important, as few
programs need more than 1000 segments, but many programs need large
segments.
The heart of the Pentium virtual memory consists of two tables, called the LDT
(Local Descriptor Table) and the GDT (Global Descriptor Table). Each program
has its own LDT, but there is a single GDT, shared by all the programs on the
computer. The LDT describes segments local to each program, including its code,
data, stack, and so on, whereas the GDT describes system segments, including
the operating system itself.
To access a segment, a Pentium program first loads a selector for that segment
into one of the machine's six segment registers. During execution, the CS register
holds the selector for the code segment and the DS register holds the selector for
the data segment. The other segment registers are less important. Each selector is
One of the selector bits tells whether the segment is local or global (i.e., whether
it is in the LDT or GDT). Thirteen other bits specify the LDT or GDT entry
number, so these tables are each restricted to holding 8K segment descriptors.
The other 2 bits relate to protection and will be explained later. Descriptor 0 is
forbidden. It may be safely loaded into a segment register to indicate that the
segment register is not currently available. It causes a trap if used.
The format of the selector has been cleverly chosen to make locating the
descriptor easy. First either the LDT or GDT is selected, based on selector bit 2.
Then the selector is copied to an internal scratch register, and the 3 low-order bits
set to 0. Finally, the address of either the LDT or GDT table is added to it, to give
a direct pointer to the descriptor. For example, selector 72 refers to entry 9 in the
GDT, which is located at address GDT + 72.
Let us trace the steps by which a (selector, offset) pair is converted to a physical
address. As soon as the microprogram knows which segment register is being
used, it can find the complete descriptor corresponding to that selector in its
internal registers. If the segment does not exist (selector 0), or is currently paged
out, a trap occurs.
The hardware then uses the Limit field to check if the offset is beyond the end of
the segment, in which case a trap also occurs. Logically, there should be a 32-bit
field in the descriptor giving the size of the segment, but there are only 20 bits
Assuming that the segment is in memory and the offset is in range, the Pentium
then adds the 32-bit Base field in the descriptor to the offset to form what is called
a linear address, as shown in Figure 3. The Base field is broken up into three
pieces and spread all over the descriptor for compatibility with the 286, in which
the Base is only 24 bits. In effect, the Base field allows each segment to start at
an arbitrary place within the 32-bit linear address space.
If paging is disabled (by a bit in a global control register), the linear address is
interpreted as the physical address and sent to the memory for the read or write.
Thus with paging disabled, we have a pure segmentation scheme, with each
segment's base address given in its descriptor. Segments are not prevented from
overlapping, probably because it would be too much trouble and take too much
time to verify that they were all disjoint.
Each running program has a page directory consisting of 1024 32-bit entries. It is
located at an address pointed to by a global register. Each entry in this directory
points to a page table also containing 1024 32-bit entries. The page table entries
point to page frames. The scheme is shown in Figure 4.
In Figure 4(a) we see a linear address divided into three fields, Dir, Page, and
Offset. The Dir field is used to index into the page directory to locate a pointer to
the proper page table. Then the Page field is used as an index into the page table
UMERA ANJUM COMPUTER OPERATING SYSTEMS 41
VIRTUAL MEMORY (REVISED VERSION)
to find the physical address of the page frame. Finally, Offset is added to the
address of the page frame to get the physical address of the byte or word needed.
The page table entries are 32 bits each, 20 of which contain a page frame number.
The remaining bits contain access and dirty bits, set by the hardware for the
benefit of the operating system, protection bits, and other utility bits.
Each page table has entries for 1024 4-KB page frames, so a single page table
handles 4 megabytes of memory. A segment shorter than 4M will have a page
directory with a single entry, a pointer to its one and only page table. In this way,
the overhead for short segments is only two pages, instead of the million pages
that would be needed in a one-level page table.
It is also worth noting that if some application does not need segmentation but is
content with a single, paged, 32-bit address space, that model is possible. All the
segment registers can be set up with the same selector, whose descriptor has Base
= 0 and Limit set to the maximum. The instruction offset will then be the linear
address, with only a single address space used - in effect, normal paging. In fact,
all current operating systems for the Pentium work this way. OS/2 was the only
one that used the full power of the Intel MMU architecture.
All in all, one has to give credit to the Pentium designers. Given the conflicting
goals of implementing pure paging, pure segmentation, and paged segments,
while at the same time being compatible with the 286, and doing all of this
efficiently, the resulting design is surprisingly simple and clean.
As long as a program restricts itself to using segments at its own level, everything
works fine. Attempts to access data at a higher level are permitted. Attempts to
access data at a lower level are illegal and cause traps. Attempts to call procedures
at a different level (higher or lower) are allowed, but in a carefully controlled
way. To make an interlevel call, the CALL instruction must contain a selector
instead of an address. This selector designates a descriptor called a call gate,
which gives the address of the procedure to be called. Thus it is not possible to
jump into the middle of an arbitrary code segment at a different level. Only
official entry points may be used. The concepts of protection levels and call gates
were pioneered in MULTICS, where they were viewed as protection rings.
A typical use for this mechanism is suggested in Figure 5. At level 0, we find the
kernel of the operating system, which handles I/O, memory management, and
other critical matters. At level 1, the system call handler is present. User programs
may call procedures here to have system calls carried out, but only a specific and
protected list of procedures may be called. Level 2 contains library procedures,
possibly shared among many running programs. User programs may call these
procedures and read their data, but they may not modify them. Finally, user
programs run at level 3, which has the least protection.
Traps and interrupts use a mechanism similar to the call gates. They, too,
reference descriptors, rather than absolute addresses, and these descriptors point
to specific procedures to be executed. The Type field in Figure 2 distinguishes
between
code segments, data segments, and the various kinds of gates.
Paging in Pentium:
Offset within page is 12 bits, and page number is 20 bits. Thus, 220
pages, So use 2-level paging
TLB used