虚拟存储器和高速缓存总结

概述

为了更加有效的管理存储器并且少出错,现代操作系统提供了一种对主存的抽象,叫做虚拟存储器。虚拟存储器是被应用程序所意识和使用的。也就是说,它是被抽象出来的,虚拟出来的主存。所以,从应用程序的层面,程序看到的和使用的虚拟地址都是属于虚拟存储器的。虚拟存储器充当一种中间转换的角色,把虚拟地址对应的主存转换到真实的主存上面。

如图:

下图便是一个虚拟存储器的表示。

虚拟存储器是不存在的,是虚拟出来的,如程序文件段,它是对应在磁盘上程序文件所在位置的代码段的,主存中可能存在着一部分或全部的缓存。运行时堆段对应着磁盘上的swap区,主存中可能存在着一部分或全部的缓存。所以,虚拟存储器也可以说对程序段的组织,当需要访问时,再到主存或者虚拟存储器指向的真正位置去取。

虚拟存储器的作用:
  • 它将主存看成是磁盘的一个高速缓存,在主存中只保留活动的区域,并根据需要在磁盘和主存之间传送数据,进而高效的利用有限的主存。
  • 它为每个程序提供了一致的地址空间(虚拟地址空间),简化了存储器管理。例如,加载、链接和共享因虚拟存储器而变的简单。
  • 它保护每个进程的地址空间不被其他进程破坏。每个进程的地址空间是私有的,即使所有进程的地址空间范围是一样的,访问的地址也可能相同,但虚拟存储器管理着进程能访问到的真实内存,假如程序访问不存在或使用错误权限访问都将返回错误。

虚拟寻址和物理寻址

程序使用虚拟寻址,物理内存使用物理寻址。

程序执行是产生一条虚拟地址,通过MMU(内存管理单元),转换为物理地址,使用该物理地址访问物理内存,取得数据。

地址空间

地址空间包括虚拟地址空间和物理地址空间。假如一个存储器的容量是N=2n字节,那么他有N个地址,n位的地址空间。

CPU产生的地址是虚拟地址,属于虚拟地址空间。现代系统有32位和64位地址空间,这个地址空间就是虚拟地址空间。

物理地址空间是用来寻址物理内存的。

地址空间的概念很重要,它清楚的区分了数据对象(字节)和它们的属性(地址)。那么可以将其推广,允许每个数据对象有多个独立的地址,其中每个地址都选自一个不同的地址空间。这也是虚拟存储器的基本思想。

虚拟存储器架构

如图:

缩写解释:

VA:虚拟地址

VPN:虚拟页号

PTE:页表项

PTEA:页表项地址

PA:物理地址

DATA:数据

MMU:内存管理单元

TLB:地址翻译缓冲器

设置存储器层次结构主要是为了缓存低速的存储器。主存是对磁盘等设备的缓存,cache是对主存的缓存,tlb是对主存页表的缓存。

寻址方式:

  • tlb是虚拟地址寻址的。
  • cache、主存是物理地址寻址的。
  • 磁盘是磁盘的方式地址寻址的。
图解:
  • CPU产生一个虚拟地址,虚拟地址传送到MMU中,MMU首先根据虚拟地址在tlb中找对应的项,对应的项中包含虚拟地址对应的物理地址,如果找到,就用得到的物理地址在cache中找物理地址对应的数据,如果找到,就把数据从cache中返回给CPU。上述的情况是最理想的情况,即tlb命中,cache也命中。
  • 如果tlb未命中,则MMU根据VA,应用一定的逻辑计算出PTE的物理地址(PTEA)。用PTEA在cache中找对应的数据(PTE),如果cache命中,把PTE返回给MMU,并填充到TLB中,下次再查找TLB时,TLB就会命中了。
  • 如果CACHE未命中,则用PA从主存中取数据,返回数据并填充CACHE对应部分,下次就可以从CACHE中命中。
  • 还有一种情况是,如果请求的数据未在主存中缓存,而是在磁盘中,例如页表项(PTE)中对应的地址是磁盘的地址,主存未命中,称为缺页,则缺页处理程序(操作系统)从主存中找到合适的位置,把磁盘中的内容填充到相应位置。

存储器的相联方式

存储器的相联方式有全相联、组相联、直接相联。关于相联方式,现在暂不更新,网上有很多讨论了。有一点,我觉得可以提下,理解相联方式,最后最好从2进制的位变化形式去理解,这样对理解虚拟地址到物理地址的转换很有好处。

主存对磁盘的缓存

主存和磁盘之间缓存的单位是页。页的大小默认是4k,也有大页2M,甚至1G的,关于大页的讨论,以后再写文章讨论。也就是说,主存缓存磁盘内容是页大小的整数倍,那么页的基地址的最后12位必然是全0的。

cache的访问速度是主存的10倍,主存的访问速度是磁盘(机械)的100000倍。所以,缺页的代价是严重的,所以主存对磁盘的相联方式采用全相联的方式,即磁盘上的一页可以放到主存的任意一页中。并且因为访问磁盘的时间很长,主存总是采用写回的方式,而不是直写。
因为主存的容量相对于磁盘的容量是很小的,所以当运行的程序多的时候,很可能发生没有闲置的主存了,这时候会发生主存页面换出(swap),页面替换处理会找到一个最近最不可能用到的物理页面换出到磁盘,然后把请求的页面放到该物理页面处。所以,系统中可分配的内存总量 = 物理内存的大小 + 交换设备的大小。交换设备可能是swap区和文件。

cache对主存的缓存

cache和主存之间缓存的单元是cache行,每个cache行是64字节。和主存对磁盘缓存不同的是,因为cache和主存的速度相差只有10倍,所以当cache miss时的开销并没有那么大。于是cache与主存之间采用简单、快速的组相联方式。采用的寻址方式是物理地址寻址。

虚拟地址和物理地址的转换

虚拟地址是属于虚拟地址空间的,物理地址是属于物理地址空间,但两者都对应着同一个数据对象。除了这个两个地址空间,其实还有一个磁盘地址空间。CPU为了取得数据,最终必须以物理地址的形式获取。

页表

页表是虚拟地址和物理地址对应的表。在内存中的表现形式是数组。操作系统负责创建和维护,每个进程都有各自的页表,都存放在主存中。页表是常驻主存的,不被换出。一个虚拟地址对应的物理地址或者磁盘地址和标记(64位字节)叫做页表项。页表项相对页表基地址(数组基地址)的偏移,是MMU根据虚拟地址和相联方式计算出来的。一般页表也按多级页表存放的,例如intel i7的页表是四级页表,但2M大页的页表就是3级页表了。多级页表可以减小页表占用的空间。

MMU

虚拟地址转换到物理地址是通过MMU完成的。MMU负责把虚拟地址和页表基地址组合成页表项的地址,然后再根据页表项中的有效位等标记检查页表项是否有效、是否在主存中。如果有效且缓存在主存中就向主存获取数据(会先尝试从cache中获取)。如果未被缓存在主存中,而是在磁盘中,则触发缺页处理程序,从磁盘换入主存中和相应的cache中。

TLB对页表的缓存

CPU每产生一个虚拟地址,访问主存,都涉及到从虚拟地址到物理地址的转换,都会访问页表,因此,如果访问的页表项被缓存在cache中,将大大提高获取数据的速度。现在的系统采用专门的cache结构——TLB,来缓存页表项。采用专门的TLB,原因有,因为有了页表基地址之后,页表项是虚拟地址寻址的,所以TLB采用虚拟地址更加方便,但cache结构是采用物理地址寻址的,所以设置了专门的TLB结构缓存页表。

TLB种类:

在X86体系的CPU里边,一般都设有如下4组TLB:

  • 第一组:缓存一般页表(4K字节页面)的指令页表缓存(Instruction-TLB)
  • 第二组:缓存一般页表(4K字节页面)的数据页表缓存(Data-TLB)
  • 第三组:缓存大尺寸页表(2M/4M字节页面)的指令页表缓存(Instruction-TLB)
  • 第四组:缓存大尺寸页表(2M/4M字节页面)的数据页表缓存(Data-TLB)

实例:intel core i7 高速缓存结构

结构化的高速缓存层次结构

说明:
  • L1cache通常包括两个单独的i-cache(指令cache)、d-cache(数据cache)
  • L3 cache是同一颗CPU多核间共用的。

i7存储器系统

说明:

L2统一TLB:Second-level Unified TLB(4-Kbyte Pages),通常称为STLB,是i7在原TLB上专门增加的又一级更大的512条目的TLB cache,这样的话TLB的缓存就不用缓存在cache系统中了,而是缓存在STLB中。当TLB和STLB都不明中的时候,MMU会把主存中的相关页表项缓存在STLB中,而非L1、L2、L3cache系统中。

i7高速缓存参数

i7详细cache结构

另外奔腾4和至强系类的cache结构:
intel高速缓存参数:

Table 1. Characteristics of the Caches, TLBs, Store Buffer, and
Write Combining Buffer in Intel 64 and IA-32 Processors

Cache or Buffer

Characteristics

Trace Cache1

• Pentium 4 and Intel Xeon processors (Based on Intel NetBurst® microarchitecture): 12 Kìops, 8-way set
associative.
• Intel Core i7, Intel Core 2 Duo, Intel® Atom™, Intel Core Duo, Intel Core Solo, Pentium M processor: not
implemented.
• P6 family and Pentium processors: not implemented.

L1 Instruction Cache

• Pentium 4 and Intel Xeon processors (Based on Intel NetBurst microarchitecture): not implemented.
• Intel Core i7 processor: 32-KByte, 4-way set associative.
• Intel Core 2 Duo, Intel Atom, Intel Core Duo, Intel Core Solo, Pentium M processor: 32-KByte, 8-way set
associative.
• P6 family and Pentium processors: 8- or 16-KByte, 4-way set associative, 32-byte cache line size; 2-way set
associative for earlier Pentium processors.

L1 Data Cache

• Pentium 4 and Intel Xeon processors (Based on Intel NetBurst microarchitecture): 8-KByte, 4-way set
associative, 64-byte cache line size.
• Pentium 4 and Intel Xeon processors (Based on Intel NetBurst microarchitecture): 16-KByte, 8-way set
associative, 64-byte cache line size.
• Intel Atom processors: 24-KByte, 6-way set associative, 64-byte cache line size.
• Intel Core i7, Intel Core 2 Duo, Intel Core Duo, Intel Core Solo, Pentium M and Intel Xeon processors: 32-
KByte, 8-way set associative, 64-byte cache line size.
• P6 family processors: 16-KByte, 4-way set associative, 32-byte cache line size; 8-KBytes, 2-way set
associative for earlier P6 family processors.
• Pentium processors: 16-KByte, 4-way set associative, 32-byte cache line size; 8-KByte, 2-way set
associative for earlier Pentium processors.

L2 Unified Cache

• Intel Core 2 Duo and Intel Xeon processors: up to 4-MByte (or 4MBx2 in quadcore processors), 16-way set
associative, 64-byte cache line size.
• Intel Core 2 Duo and Intel Xeon processors: up to 6-MByte (or 6MBx2 in quadcore processors), 24-way set
associative, 64-byte cache line size.
• Intel Core i7, i5, i3 processors: 256KBbyte, 8-way set associative, 64-byte cache line size.
• Intel Atom processors: 512-KByte, 8-way set associative, 64-byte cache line size.
• Intel Core Duo, Intel Core Solo processors: 2-MByte, 8-way set associative, 64-byte cache line size
• Pentium 4 and Intel Xeon processors: 256, 512, 1024, or 2048-KByte, 8-way set associative, 64-byte cache
line size, 128-byte sector size.
• Pentium M processor: 1 or 2-MByte, 8-way set associative, 64-byte cache line size.
• P6 family processors: 128-KByte, 256-KByte, 512-KByte, 1-MByte, or 2-MByte, 4-way set associative,
32-byte cache line size.
• Pentium processor (external optional): System specific, typically 256- or 512-KByte, 4-way set associative,
32-byte cache line size.

L3 Unified Cache

• Intel Xeon processors: 512-KByte, 1-MByte, 2-MByte, or 4-MByte, 8-way set associative, 64-byte cache line
size, 128-byte sector size.
• Intel Core i7 processor, Intel Xeon processor 5500: Up to 8MByte, 16-way set associative, 64-byte cache
line size.
• Intel Xeon processor 5600: Up to 12MByte, 64-byte cache line size.
• Intel Xeon processor 7500: Up to 24MByte, 64-byte cache line size.

Instruction TLB
(4-KByte Pages)

• Pentium 4 and Intel Xeon processors (Based on Intel NetBurst microarchitecture): 128 entries, 4-way set
associative.
• Intel Atom processors: 32-entries, fully associative.
• Intel Core i7, i5, i3 processors: 64-entries per thread (128-entries per core), 4-way set associative.
• Intel Core 2 Duo, Intel Core Duo, Intel Core Solo processors, Pentium M processor: 128 entries, 4-way set
associative.
• P6 family processors: 32 entries, 4-way set associative.
• Pentium processor: 32 entries, 4-way set associative; fully set associative for Pentium processors with MMX
technology.

Data TLB (4-KByte
Pages)

• Intel Core i7, i5, i3 processors, DTLB0: 64-entries, 4-way set associative.
• Intel Core 2 Duo processors: DTLB0, 16 entries, DTLB1, 256 entries, 4 ways.
• Intel Atom processors: 16-entry-per-thread micro-TLB, fully associative; 64-entry DTLB, 4-way set
associative; 16-entry PDE cache, fully associative.
• Pentium 4 and Intel Xeon processors (Based on Intel NetBurst microarchitecture): 64 entry, fully set
associative, shared with large page DTLB.
• Intel Core Duo, Intel Core Solo processors, Pentium M processor: 128 entries, 4-way set associative.
• Pentium and P6 family processors: 64 entries, 4-way set associative; fully set, associative for Pentium
processors with MMX technology.

Instruction TLB
(Large Pages)

• Intel Core i7, i5, i3 processors: 7-entries per thread, fully associative.
• Intel Core 2 Duo processors: 4 entries, 4 ways.
• Pentium 4 and Intel Xeon processors: large pages are fragmented.
• Intel Core Duo, Intel Core Solo, Pentium M processor: 2 entries, fully associative.
• P6 family processors: 2 entries, fully associative.
• Pentium processor: Uses same TLB as used for 4-KByte pages.

Data TLB (Large
Pages)

• Intel Core i7, i5, i3 processors, DTLB0: 32-entries, 4-way set associative.
• Intel Core 2 Duo processors: DTLB0, 16 entries, DTLB1, 32 entries, 4 ways.
• Intel Atom processors: 8 entries, 4-way set associative.
• Pentium 4 and Intel Xeon processors: 64 entries, fully set associative; shared with small page data TLBs.
• Intel Core Duo, Intel Core Solo, Pentium M processor: 8 entries, fully associative.
• P6 family processors: 8 entries, 4-way set associative.
• Pentium processor: 8 entries, 4-way set associative; uses same TLB as used for 4-KByte pages in Pentium
processors with MMX technology.

Second-level Unified
TLB (4-KByte
Pages)

• Intel Core i7, i5, i3 processor, STLB: 512-entries, 4-way set associative.

Cache or Buffer

Characteristics

i7地址翻译

说明:

VPN和VPO的翻译是同步进行的,在用VPN查找页表中对应的PPN的同时,用VPO(12位)查找L1 cache(6+6位)取得其中的标记,再用PPN和标记比较,检查是否命中。

i7页表翻译

不太复杂就不解释了。

参考文献

  • 深入理解计算机系统(原书第3版)
  • Intel®64 and IA-32 Architectures Software Developer’s Manual Volume 3A: SystemProgramming Guide, Part 1

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
目录 第一章 Linux底层分段分页机制 5 1.1 基于x86的Linux分段机制 5 1.2 基于x86的Linux分页机制 7 1.2.1 页全局目录和页表 8 1.2.2 线性地址到物理地址 10 1.2.3 线性地址字段处理 13 1.2.4 页表处理 15 1.3 扩展分页与联想存储器 20 1.4 Linux内存布局 21 1.5 内核空间和用户空间 23 1.5.1 初始化临时内核页表 24 1.5.2 永久内核页表的初始化 32 1.5.3 第一次进入用户空间 41 1.5.4 内核映射机制实例 44 1.6 固定映射的线性地址 48 1.7 高端内存内核映射 50 1.8.1 永久内存映射 50 1.8.2 临时内核映射 55 第二章 内核级内存管理系统 58 2.1 Linux页面管理 58 2.1.1 NUMA架构 61 2.1.2 内存管理区 62 2.2 伙伴系统算法 65 2.2.1 数据结构 66 2.2.2 块分配 67 2.2.3 块释放 69 2.3 Linux页面级内存管理 72 2.3.1 分配一组页面 73 2.3.2 释放一组页面 80 2.4 每CPU页面高速缓存 81 2.4.1 数据结构 81 2.4.2 通过每CPU 页高速缓存分配页面 82 2.4.3 释放页面到每CPU 页面高速缓存 83 2.5 slab分配器 85 2.5.1 数据结构 86 2.5.2 分配/释放slab页面 92 2.5.3 增加slab数据结构 93 2.5.4 高速缓存内存布局 94 2.5.5 slab着色 95 2.5.6 分配slab对象 96 2.5.7 释放Slab对象 100 2.5.8 通用对象 102 2.5.9 内存池 103 2.6 非连续内存区 104 2.6.1 高端内存区回顾 105 2.6.2 非连续内存区的描述符 106 2.6.3 分配非连续内存区 109 2.6.4 释放非连续内存区 113 第三章 进程的地址空间 117 3.1 用户态内存分配 117 3.1.1 mm_struct数据结构 118 3.1.2 内核线程的内存描述符 122 3.2 线性区的数据结构 123 3.2.1 线性区数据结构 123 3.2.2 红-黑树算法 126 3.2.3 线性区访问权限 128 3.3 线性区的底层处理 130 3.3.1 查找给定地址的最邻近区 131 3.3.2 查找一个与给定的地址区间相重叠的线性区 135 3.3.3 查找一个空闲的地址区间 135 3.3.4 向内存描述符链表中插入一个线性区 137 3.4 分配线性地址区间 141 3.5 释放线性地址区间 151 3.5.1 do_munmap()函数 151 3.5.2 split_vma()函数 153 3.5.3 unmap_region()函数 155 3.6 创建和删除进程的地址空间 156 3.6.1 创建进程的地址空间 156 3.6.2 删除进程的地址空间 175 3.6.3 内核线程1号的地址空间 176 3.7 堆的管理 178 第四章 磁盘文件内存映射 182 4.1 内存映射的数据结构 182 4.2 内存映射的创建 184 4.3 内存映射的请求调页 194 4.4 刷新内存映射的脏页 203 4.5 非线性内存映射 210 第五章 页面的回收 215 5.1 页框回收概念 215 5.1.1 选择目标页 216 5.1.2 PFRA设计 217 5.2 反向映射技术 218 5.2.1 匿名页的反向映射 220 5.2.2 优先搜索树 226 5.2.3 映射页的反向映射 231 5.3 PFRA实现 235 5.3.1 最近最少使用(LRU)链表 236 5.3.2 内存紧缺回收 242 5.3.3 回收磁盘高速缓存的页 267 5.3.4 周期回收 273 5.3.5 内存不足删除程序 283 第六章 交换机制 289 6.1 交换区数据结构 289 6.1.1 创建交换区 290 6.1.2 交换区描述符 291 6.1.3 换出页标识符 293 6.2 激活和禁用交换区 295 6.2.1 sys_swapon()系统调用 296 6.2.2 sys_swapoff()系统调用 304 6.2.3 try_to_unuse()函数 308 6.3 分配和释放页槽 313 6.3.1 scan_swap_map()函数 313 6.3.2 get_swap_page()函数 316 6.3.3 swap_free()函数 318 6.4 页面的换入换出 320 6.4.1 交换高速缓存 320 6.4.2 换出页 323 6.4.3 换入页 329 第七章 缺页异常处理程序 335 7.1 总体流程 335 7.2 vma以外的错误地址 341 7.3 vma内的错误地址 346 7.3.1 handle_mm_fault()函数 348 7.3.2 请求调页 352 7.3.3 写时复制 358 7.4 处理非连续内存区访问 364

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值