FIVE drlhgsd:kfccqccjg

文章目录

  • 5.1 yy
  • 5.2 存储器技术
  • 5.3cache的基原
      • 这一节先看一简单cache,
      • 观察图5-7,两问题要解决:
      • 若cache中的块数是2的幂,取模很简单,
      • 图5-8
      • cache中每个位置可能对应于主存中多个不同的地址,
      • 还要一法判断cache块中确实没包含有效信息。
      • 本节剩余,
      • 重点
    • 5.3.1 cache访问
  • 5.4cache性能评估和改进
    • 5.4.5 通过分块进行软件优化
      • 存储器层次对程序性能有大影响,
      • 处理数组时,
      • 与对一个数组进行整行或整列操作不同,
      • DGEMM的内循环(3章中图3-21中的4~9行)如下:
      • 缺失的次数依赖N和cache容量。
      • 若cache中能保持N×N的矩阵和一个长为N的行,
      • 为确保正在访问的元素能够在cache中命中,
      • 图5-21是DGEMM的分块版本。
      • 图5-22:用分块之后对三个数组的访问情况。
      • 虽然分块技术的目标是降低 cache缺失率,
      • 图5-23:采用分块技术 DGEMM的性能产生的影响,
  • 5.5可信存储器层次
  • 5.6虚拟机
  • 5.7虚存
      • 用虚存的二动机是许单用户程序使用超过主存容量
      • 虚存的发明将程序员解脱出来
      • 尽管虚存和cache工作原理一样,但术语不同
      • 图5-26
    • 5.7.1 页的存放和查找
      • 第二段
      • 软件-硬件接口
      • 第三段
      • 图5-27
    • 5.7.2 缺页故障
      • 虚拟地址并不马上告诉我们页在磁盘的位置
      • 由于我们无法提前获知存储器中的某一页什么时候被替换出去
      • 图5-28
      • OS同样建一个数据结构来记录使用每个物理页的是哪些进程和哪些虚拟地址。
      • 硬软接口
      • 精解
        • 界限寄存器
        • 允许地址空间一个方向增长不够哦
        • 另外一种减小页表容量的方法是
    • 5.7.3 关于写
      • 访cache和主存的时间相差上百周期,
      • 硬件/软件接口
    • 5.7.4 加快地址转换:TLB
      • so modern处理器都包含一个特殊的cache以跟踪最近使用的过的地址变换
      • 如图5-29,TLB
      • 图5-29
      • 每次访问,在TLB查找虚号
      • TLB缺失既可
      • 下段
      • TLB的一些典型值
      • TLB设计中相联度设置多样化
      • 内置FastMATH TLB
      • 图5-30
      • 图5-30是TLB和一个cache
      • 图5-31
      • 对于写,
    • 5.7.5 集成虚拟存储器、TLB和cache
      • 最好情况
      • 例题:存储器层次结构的全部操作
        • 答案(图5-32)
      • 精解
    • 5.7.6 虚拟存储器中的保护
      • 精解
    • 5.7.7 cope TLB缺失和缺页
    • 5.7.8 小结
  • 5.10 并行与存储器层次结构: cache一致性
    • 5.10.1 实现一致性的基本方案
    • 5.10.2监听协议
  • 5.15谬误和陷阱
    • 陷阱:写程序或编译器生成代码时忽略存储系统的行为。
    • 陷阱:模拟cache时,忘记说明字节编址或cache块大小
      • 模拟cache时(手动或者通过计算机),
      • 同样须说明块大小。
      • 包括作者(在早期的书稿中)
    • 陷阱:对于共享 cache,组相联度少于核的数量或者共享该 cache的线程数。
    • 阱:用存储器平均访问时间来评估乱序处理器的存储器层次结构。
      • 若处理器在cache缺失时阻塞,那么你可以分别计算存储器阻塞时间和处理器执行时间,因此可以使用存储器平均访问时间来独立地评估存储器层次结构(见5.4节第2例)。
      • 如果处理器在cache缺失时继续执行指令,甚至可能维持更多的cache缺失,
  • 5.18练习题
    • 5.1
      • 5.1.1
      • 5.1.2
      • 5.1.3
      • 局部性受访问顺序和数据存放位置的影响。
      • 5.1.4
      • 5.1.5
      • 5.1.6
    • 5.2
      • 5.2.1
      • 5.2.2

5.1 yy

5.2 存储器技术

5.3cache的基原

  • 图书馆例子中,书桌就好比是高速缓存
    • 一个存放待用(书籍)的安全场所。
  • 早期的商业计算机中, cache是处理器和主存间的特殊层次。
  • 在4章的数据通路中,存储器就被cache替代了。
  • cache的使用占主导,
    • 也指代那些基于局部性原理来管理的存储器。
  • cache最早出现60年代早期的研究型计算机
    • 后期被应用于产品型计算机。
  • 如今生产的每一台通用计算机,
    • 从服务器到低功耗嵌入式处理器,
    • 都有cache。

这一节先看一简单cache,

  • 处理器每次请求一个字,每个块也由一个字组成(已熟悉cache基本原理的读者可以跳至5.4节)。
  • 图5-7是简单cache,要访问的数据项最初不在cache中。
  • 在请求发出前,cache保存最近访问过的数据项 X 1 , X 2 , ⋯   , X n − 1 X_1,X_2,\cdots,X_{n-1} X1,X2,,Xn1的集合,
  • 而当前处理器所要访问的 X n X_n Xn,并不在cache中。
  • 该请求导致一次缺失, X n X_n Xn被从主存调人cache。
FIVE drlhgsd:kfccqccjg_第1张图片

观察图5-7,两问题要解决:

  • 怎样知道一个数据项是否在cache?

  • 如果数据项在 cache中,如何找到它?

    • 这两个问题的答案是相关的。
  • 若每个字都放在cache中确定位置,那么只要它在cache,就能直接找到。

  • 在cache中为主存中每个字分配一个位置的最简单方法是

    • 根据这个字的主存地址进行分配,
    • 这种cache结构称为直接映射
    • 每个存储器地址对应cache中一确定地址。
  • 对直接映射cache来说,主存地址和cache位置之间的典型映射通常比较简单。

    • 几乎所有的直接映射 cache都用
      ( 块 地 址 ) m o d ( c a c h e 中 的 块 数 ) (块地址)mod(cache中的块数) ()mod(cache)
  • 直接映射:一种cache結构,

    • 每个存储器地址仅对应到cache中的一个位置

若cache中的块数是2的幂,取模很简单,

  • 只需取地址的低log2(块中的cache容量)位。
  • 一个8块的cache可使用块地址中最低的三位
  • 图5-8中,直接映射的cache块为8个字,
  • 存储器地址00001到11101被映射到cache中001到101

图5-8

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jystYawG-1593352281181)(?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pob3V0aWFuemkxMg==,size_16,color_FFFFFF,t_70)]

FIVE drlhgsd:kfccqccjg_第2张图片
  • 主存地址0~31被映射到cache中的相同位置,该cache有8个字。
  • cache中有8个字
    • 地址X被映射到直接映射cache字Xmod8,
    • 即低3位被用作cache索引。
  • 地址00001 01001、10001和11001对应cache中001块,
  • 00101、01101、10101和11101对应101块

cache中每个位置可能对应于主存中多个不同的地址,

  • 咋知道cache中的数据项是否是所请求的字呢?
  • 即如何知道所请求的字是否在cache中?
  • 可在cache中增加组标记(tag),标记中包含了
    • 地址信息,可用来判断 cache中的字是否就是所请求的字。
  • 标记只需含地址高位,
    • 没用来检索cache的那些位。
  • 图5-8中,标记位只需用5位地址中的高两位,低3位的索引域则用来选择cache中的块。
  • 按照定义,任何一个可以放人相同 cache块中的字的地址的索引域一定是那个块的块号,因此标记位无需包含这些冗余的索引位。
  • 标记:表中的一个字段,包含地址信息,
    • 可用来判断cache中的字是否就是所请求的字。

还要一法判断cache块中确实没包含有效信息。

  • 当处理器启动时, cache中无数据,标记域中的值无意义。
  • 甚至在执行了一些指令后, cache中的一些块依然为空,如图5-7。
  • 因此,在 cache中,这些块的标记应该被忽略。
  • 方法就是增加一个有效位( valid bit)来标识一个块是否含有一个有效地址。
  • 如果该位没有被设置,则不能使用该块中的内容。
  • 有效位:
    • 表中的一个字段,标识一个块是否含有一个有效数据。

本节剩余,

  • 将重点说明如何在cache中读。
  • 读不改变 cache中内容,因而处理时比写要简单
  • 在探讨了读和 cache缺失如何处理的基本原理后,
  • 将介绍实际计算机中 cache的设计以及 cache如何处理写

重点

  • cache可能是预测技术中最重要的例子。
  • 它依赖局原
    • 尽可能在存储器层次结构的更高一层中找所需数据,
    • 且当预测错时提供
      • 能够从存储器层次的更低一层中找到并获取正确数据的机制。
  • 现代计算机cache预测命中率>95%(见图5-47)。

5.3.1 cache访问

写到这儿了

5.4cache性能评估和改进

5.4.5 通过分块进行软件优化

存储器层次对程序性能有大影响,

  • 对cache中数据重用,提升数据的
    • 时间局部性并因此降低缺失率
  • 可大大提高cache的性能。

处理数组时,

  • 将数组元素按访问顺序存放在存储器中,则能够获得很好性能。
  • 假定要处理多个数组,有些按行,有些按列
  • 在每次循环迭代中,既有按行访问的数组,又有按列访问的数组,
    • so无论用按行存储或按列存储的
    • 方式都不能解决问题。

与对一个数组进行整行或整列操作不同,

  • 分块算法对子矩阵(或称为块)操作。
  • 在数据被替换出去之前,最大限度地对已装入cache的数据访问,即通过提升时间局部性的方法来降低 cache缺失率。

DGEMM的内循环(3章中图3-21中的4~9行)如下:

FIVE drlhgsd:kfccqccjg_第3张图片

  • 读B中的所有 N × N N\times N N×N个,
    • 另外反复读取了A中对应 行中的N个,
    • 且对 C C C中对应行的N个元素进行写。
    • (注释使得矩阵的行列更容易识别。)
  • 图5-20给出了访问三个数组的情況。
  • 深色:一次最近访问的元素,
    • 浅色:早期访问的元素,
    • 白色还没有被访问的元素。

FIVE drlhgsd:kfccqccjg_第4张图片

  • N=6,i=1。
    白色表该元素未被访问,浅色表早期访问,深色表新的访问。
  • 与图5-21相比,反复读取A和B的元素以计算新的元素x。
  • 行列边上的变量i、j和k用于表示对数组的访问

缺失的次数依赖N和cache容量。

  • 如果不发生冲突前提下
    • 三个N×N矩阵都在cache中,则无问题。
  • 设大小32×32。
  • 三矩阵占24KiB,Core i7( Sandy Bridge)中32KiB的数据cache足够

若cache中能保持N×N的矩阵和一个长为N的行,

  • 则A的第i行和B可驻留在cache中。
  • 如果cache容量再小,可能导致B和C访问都缺失。
  • 最坏情况, N 3 N^3 N3次操作需要 2 N 3 + N 2 2N^3+N^2 2N3+N2次存储器字的访问。

为确保正在访问的元素能够在cache中命中,

  • 可改为每次循环迭代只计算一个子矩阵。
  • 通过参数BLOCKSIZE使第4章图4-80中
    • 的DGEMM程序循环处理大小为BLOCKSIZE的数组、
    • 称分块因子

图5-21是DGEMM的分块版本。

  • do_block用si、sj和sk表示每个子数组的起始位置。
  • do_block的内层循环以BLOCKSIZE为步进长度进行计算,
    • 而不是B和C的长度。
  • gcc优化器通过“inling”功能去除任何调用开销;也就是说,它将直接插入代码以避免传统的参数传递和返回地址的保存与恢复。

FIVE drlhgsd:kfccqccjg_第5张图片

  • 假定C初始化为0。
  • doblock来源于第3章中的基本DGEMM,用了新参数来指明大小为 BLOCKSI2E的子矩阵的起始位置。
  • gcc优化器通过内联的dob1ck函数消除函数开销

图5-22:用分块之后对三个数组的访问情况。

  • 只考虑容量失效,访问存储器的总字数为 2 N 3 / B L O C K S I Z E + N 2 2N^3/BLOCKSIZE+N^2 2N3/BLOCKSIZE+N2次,为原来的1/BLOCKSIZE。
  • 分块技术同时利用了空局和时局,访问A时利用空局,B时用时局

FIVE drlhgsd:kfccqccjg_第6张图片

虽然分块技术的目标是降低 cache缺失率,

  • 但也可用来帮助寄存器的分配。
  • 通过用较小的分块,使得一个块可驻留在寄存器中,程序中可以将load和 store操作的数量大大减少,从而提高性能

图5-23:采用分块技术 DGEMM的性能产生的影响,

  • 其中矩阵尺寸逐渐增加。
  • 当尺寸增大到不能在cache中完全容纳这三个矩阵时,
    • 性能下降为最优情况的一半。
  • 即使矩阵尺寸为960×x960时(是3章和4章尺寸的900倍),
    • 性能仅下降了不到10%。
FIVE drlhgsd:kfccqccjg_第7张图片

写到这儿了

5.5可信存储器层次

5.6虚拟机

5.7虚存

在这里插入图片描述

  • 主存为usually由磁盘实现的辅存 充当cache
  • 此技术叫虚拟存储器
    • 俩动机
      • 允许云计算在多个虚拟机之间有效而安全的共享存储器
      • 消除一个小的主存容量对程序设计造成的影响

在这里插入图片描述

  • 为许多个虚拟机共享同一个存储器
  • 需在虚拟机之间进行保护
  • 程序只可对 给他的那部分主存 读写
  • 主存只存放 众多程序中活跃的
    • 像cache只 存放 程序中活跃的
  • 局部性原理同样适用啥?
  • 虚拟存储器使更有效地共享处理器和主存

  • 编译时不知哪些虚拟机共享存储器
  • in fact ,when vm runs,vm共享存储器是动态变化的
  • 程序都编译到它自己的地址空间
    • 存储器中只有该程序访问的独立的一串地址
    • 谁实现程序地址空间到物理地址空间的转换

在这里插入图片描述

用虚存的二动机是许单用户程序使用超过主存容量

  • 以前如果一个程序对存储器来说太大
    • 程序员需要将它变成合适的大小
  • 程序员将
    • 程序划分成许多段,并将其标为互斥
    • 程序段在执行时候由用户程序控制装入或换出
    • 保证不会访问没有装在的程序段
    • 且装载的程序段不会超过存储器总容量
  • 传统的程序段被构造成模块
    • 每一个都包含数据和代码
    • 不同模块的调用将导致一个模块覆盖掉另一个

虚存的发明将程序员解脱出来

  • 虚存自动管理由主存(为了区别虚存,有时也叫物理存储器)
    • 和辅助存储器组成的两级存储器层次结构

尽管虚存和cache工作原理一样,但术语不同

  • 虚存中
    • 块被称为页
    • 访问缺失就是缺页
  • 虚存中
    • 处理器产生一个虚拟地址
    • 再结合软硬件转换成物理地址
    • 然后就可用来访问主存了
  • 5-25显示一个分页的虚拟寻址的存储器被映射到主存中
    • 此过程称为地址映射或地址转换
  • 如今个人移动设备中由虚拟存储器控制的两级存储器层次结构是
    • DRAM和闪存
  • 服务器中则是
    • DRAM和磁盘
  • 图书馆类比
    • 书名就是虚拟地址
    • 图书馆的位置则是物理地址
      • 可能是图书馆的索书号

  • 虚存还提供重定位来简化执行时程序加载过程
  • 用地址访存前
    • 重定位将程序所用的虚址映射到不同的物理地址
  • 重定位方法许我们将程序加载到主存中的任何位置
  • 现今所有的虚存系统将程序重定位成一组固定大小的块(页)
    • 因此减少了寻找主存中连续的块来放置程序的必要
    • 取而代之的是
      • 操作系统只需在主存中找到足够数量的页

  • 虚存中:地址被划为虚页号和页偏移
  • 图5-26是虚页号到物理页号的转换
  • 物理页号构成物理地址的高位部分
    • 而页偏移不变
    • 构成物理地址低位
  • 页偏移域的位数决定页大小
  • 虚拟地址可寻址的页数
    • 与物理地址可寻址的页数可不同
  • 虚页数>>物理页数是描述
    • 没有容量限制的
    • 虚拟存储器的假象的基础

图5-26

  • 存储器中物理页数多少?
    • GB(gigabyte)是十进制的容量单位,1GB等于1,000,000,000Bytes。
    • 而二进制的容量单位则是用GiB(Gibibyte)就是Giga Binary Byte,相等于1,073,741,824Bytes。

  • 页缺失引发高代价是设计虚存的原因
  • 虚存中缺失叫缺页
  • 一次缺页数百万(5.2节的表说主存比磁盘块10万)
  • 这一缺失代价
    • 主要由取到标准大小的页中第一个字所需时间来定
  • 因此设计虚存时需考虑一些关键性因素
    • 为弥补大的访时,页应大。
      • 目前4-16KiB
      • 32-64KiB的台式机和服务器在研发
      • 但新的嵌入式系统相反页大小1KiB
    • 能降低缺页率的组织结构
      • 就是允许存储器中的页以全相联方式放置
    • 缺页可用软件处理
      • 这是因为与访磁相比,此开销不大
      • 此外,软件可用更先进算法选择替换页
      • 只要缺失率减少很小就可弥补算法开销
    • 由于写时间太长
      • 因此虚存中,写直达不能很好管理写操作
      • so 虚存都写回机制

这儿的精解

5.7.1 页的存放和查找

  • 缺页代价贼高
    • 所以要对页的放置进行优化来降低缺页率
  • 如果允许一虚拟页映射到任一个物理页
    • 那么缺页发生时
    • 操作系统可任一页进行替换
  • 如:os可用复杂算法数据结构来跟踪页的使用情况
    • 以选择较长一段时间不用到的页
  • 更先进灵活的策略降低缺页率
    • 也使全相联方式下页的放置变easy

第二段

  • 如5.4节提,全相联映射难在于项的定位
    • because它可在较高的存储器层次中任位
    • 全部检索不可行
  • 虚存中,用一个索引存储器中的表定位页
    • 就是页表
    • 他被放在存储器中
  • 页表用虚址中的页号做索引
    • 来找物理页号
  • 每个程序都有自己页表
    • 用来将它的虚拟地址映射到主存
  • 图书馆类比
    • 页表就是
    • 书名和藏书位置的映射
    • 就像卡片目录可能包含学校中另一个图书馆中的书
    • 而不仅是本地的分馆
    • 页表也可能包含不在存储器中的页的条目
  • 为指出页表在存储器中位置:
    • 硬件有个指向页表首地址的寄存器
    • 叫页表寄存器
    • 俺们假定页表存在存储器中一个固定的连续区域内
  • 页表:虚址到物址转换的表
    • 在主存里
    • 用虚页号索引
    • 如这个虚页当前在主存中
    • 页表中的项将包含虚页对应的物理页号

软件-硬件接口

  • 页表,程序基数器,寄存器
    • 定一虚拟机的状态
  • 如我们想让另一个虚拟机用处理器
    • 俺必须保存该状态
    • 随后恢复该状态,虚拟机就可继续执行
    • 称该状态为进程
  • 如一进程占据了处理器
    • then这进程是活跃的
    • 否则非活跃
  • OS可通过加载进程的状态令一个进程活跃起来
    • 同时激活PC
    • 进程将在PC中保存的值开始执行
  • 进程的地址空间、它在主存中可访问的所有数据
    • 都由主存中的页表所定义
  • OS只简单的加载页表寄存器用来指向它想激活的进程的页表
    • 而不是保存整个页表
  • 不同进程用相同虚址
    • so每进程有各自的页表
  • OS负责分配物理主存和更新页表
    • 因此不同进程的虚拟地址空间不冲突
  • 很快会看到
    • 使用分离的页表同样能分别保护进程

第三段

  • 图5-27用页表寄存器、虚拟地址、被指向的页表
    • 来说明如何形成物理地址
  • 每个页表用1位有效位
  • 就像在cache中的一样
  • 如果该位无效,该页不在主存,就缺页啦!
  • 若有效,该页在主存,且该项包含物理页号

图5-27

  • 用虚页号来索引页表以获得对应的物理地址部分
  • 假定地址32位
  • 页表的首地址由页表指针给出
  • 页大小 2 12 2^{12} 212字节,4KiB
  • 虚拟地址空间 2 32 2^{32} 232字节,4GiB
  • 物理地址空间是他的1/4
  • 页表项数 2 20 2^{20} 220
  • 图中所示的页表项宽度19位
    • 但为寻址方便,让他32位
    • 其他位来存放每页要保留的附加信息
    • 如保护信息
  • 由于页表包含了每个可能的虚拟页的映射
    • 因此不要标记位
  • 在cache术语中
    • 索引时用来访问页表的
    • 由整个块地址即虚页号组成
    • 这啥啊啊啊啊啊啊啊!

5.7.2 缺页故障

  • 如果虚拟页有效位关闭,就缺页故障
  • Os获得控制权。
  • 控制的转移由异常机制完成
    • 这点在第四章已看到,并在本节稍后讨论
  • 一旦OS获控制权
    • 他必须在下一级存储器层次(闪存or磁盘)
    • 找到该页
    • 然后决定将其放到主存

虚拟地址并不马上告诉我们页在磁盘的位置

  • 图书馆作类比,不能仅靠书名就找到图书的位置。
    • 而是按目录査找,获得书在书架上的位置信息,比如说图书馆的索引书号。
  • 同样,
    • 在虚存中,
    • 必须跟踪记录虚址空间的
    • 每一页在磁盘上的位置。

由于我们无法提前获知存储器中的某一页什么时候被替换出去

  • 因此OS在创建进程的时候
    • 通常在闪存或磁盘上为进程的所有页创建空间
  • 这一磁盘空间叫交换区
  • 同时创建数据结构记录每虚拟页在磁盘上的存放位置
  • 这个数据结构可能是页表中的一部分
    • 也可能是辅助数据结构
    • 寻址方式和页表一样
  • 图5-28是个包含物理页号或磁盘地址的单个表的结构
  • 交换区 :为进程的全部虚拟地址空间所预留的磁盘空间

图5-28

FIVE drlhgsd:kfccqccjg_第8张图片
  • 页表将虚拟存储器中的每一页映射到
    • 主存中的一页或存储结构的下一层(磁盘上的页)。
  • 虚页号检索页表。
  • 若有效位开启,页表提供虚页对应的物理页号(如存储器中该页的首地址)。
  • 若关闭,该页就只存在磁盘上的某个指定的磁盘地址。
  • 许多系统中,物理页地址和磁盘页地址的表在逻辑上是一个表,但存在两个独立的数据结构中。
    • 因为即使有些页当前不在主存中,也必须保存所有页的磁盘地址,so用双表在某种程度上合理
  • 主存中的页和磁盘上的页大小=

OS同样建一个数据结构来记录使用每个物理页的是哪些进程和哪些虚拟地址。

  • 当缺页发生时,若主存中所有的页都在使用,OS仍必须选择一页进行替换。
  • 希望最小化缺页的次数,大多数OS会选择近期内不会被用的页替换。
  • OS遵循5.4节的LRU
  • OS査找最近最少使用的页,
    • 假定某一页在很长一段时间都没有被访问,
    • 那么该页再被访问的可能性比最近经常访问的页的可能性要小。・
    • 被替换的页写人磁盘交换区。
  • 若还不明白,可把OS看成是另一个进程,
    • 而那些控制主存的表也在主存中;
    • 这看起来似乎有些矛盾,稍后将具体解释。

硬软接口

  • 要准确执行LRU算法代价太高
    • 因为每次存储都要更新数据结构
  • 大多数操作系统通过跟踪哪些页最近被使用
    • 哪些页最近没有用来近似实现LRU算法
  • 为帮助OS估算最近最少使用的页
    • some计算机提供一个引用位或叫使用位
    • 当一页被访问时该位被置位
  • OS定期将引用位清零
    • 然后再重新记录
    • 这样就可判定这段时间哪些页被访问过
  • 有了这些使用信息
    • OS就可从那些最近最少访问的页中选择一页
    • (通过检查引用位是否关闭)
  • 若硬件不提供这一位
    • OS就通过其他方法估计哪些页被访问过
  • 引用位 :每当访问一页时,该页被置位,用来实现LRU或其他替换策略

精解

  • 虚址32位,页大小4KiB,页表每一项4字节
    • 页表容量: 2 32 / 2 12 ∗ 4 = 4 M i B 字 节 2^{32}/2^{12}*4=4MiB字节 232/2124=4MiB
    • 也就是每个程序执行都要4MiB空间
    • 如果有很多进程同时运行,每个程序有各自页表,这会咋?
    • 如64位地址,则要 2 52 2^{52} 252个字!
  • 一系列技术用于减少页表所需的存储量。
  • 下5技术都是
    • 针对减少所需的最大存储量
    • 及减少用于页表的主存

界限寄存器

  • 对给定的进程限制其页表大小
  • 如果虚拟页号 > > >界限寄存器中值
    • 就必须在页表中加入该项
  • 这种技术允许页表随着进程消耗空间大而大
  • so只有当进程使用虚址空间的许多页时
    • 页表才很大
  • 此技术要求地址空间只朝着一方向扩展

允许地址空间一个方向增长不够哦

  • 多数语言要两种大小可扩展的区域:保留栈,保留堆。
  • 由于这种二元性,如果将页表划分,使其既能从最高地址向下扩展,也能从最低地址向上扩展,就方便了。
  • 这意味着有两个独立的页表和两个独立的界限。
  • 两个页表的使用将地址空间分成两段。
  • 地址的高位用来判断该地址使用了哪个段和哪个页表。
  • 由于段由地址的高位部分决定,每一段可以有地址空间的一半大。
  • 每段的界限寄存器指定了当前段的大小,该大小以页为单位增长。
  • 这种类型的段被应用于很多体系结构,包括MIPS。
  • 不同于5.7节的第三个精解中讨论的段,这种形式的段对应用程序不可见的,对OS可见。
  • 主要的缺陷在于当以一种稀疏方式使用地址空间而不是一组连续的虚拟地址时,它的执行效果就不太好

另外一种减小页表容量的方法是

  • 对虚拟地址使用哈希,
  • 这样,页表需要的容量仅仅是主存中的物理页数。
  • 这种结构称为反置页表( inverted page table)。
  • 当然,反置页表的查找过程有些复杂,因为不能仅依靠索引来访问页表。

还有嗲没写

5.7.3 关于写

访cache和主存的时间相差上百周期,

  • 写直达机制也可用,但需一个写缓冲区来隐藏写延迟。
  • 虚存中,对存储器层次结构中下一层(磁盘)的写
    • 需数百万个处理器周期;
    • 创建一个缓冲区用来
      • 允许系统用写直达的方式对磁盘进行写
      • 完全不可行的。
  • 虚存必须用写回机制,
    • 对存储器中的页进行单独的写
    • 且在该页被替换出存储器时
    • 再被复制到磁盘中去。

硬件/软件接口

  • 虚存中,写回另个优点。
    • 相对于磁盘访问时间,其传输时间少得多,
    • so把整页复制回磁盘比把单个字写回高效
  • 尽管写回比传输单个字更高效,但开销却很大。
    • 因此,当某页被替换时,希望知道该页是否需要被复制写回。
  • 为追踪读入主存中的页是否被写过,可在页表中增加一个脏位
    • 当页中任何字被写时就将这一位置位。
  • 若OS选择替换某一页,
    • 脏位:在把该页所占用的主存让给另一页之前,是否将该页写回磁盘。
    • so一个修改过的页常被称脏页

5.7.4 加快地址转换:TLB

  • because页表放在主存,so程序每次访存至少需俩次
    • 一次访存获物理地址
    • 二次访存才得数据
  • 提高访问性能的关键在于依靠页表的访问局部性
  • 当一转换的虚页号被使用时,可再会被使用
    • 因为对该页中字的引用
    • 同时有时间局部性和空间局部性

so modern处理器都包含一个特殊的cache以跟踪最近使用的过的地址变换

  • 此特殊的地址转换cache称快表
    • 叫地址变换高速缓存更精确
  • TLB相当于记录目录中的一些书的位置的小纸片
    • 在纸片上记录一些书的位置
    • 并将小纸片当成图书馆索书号的cache
    • 这样就不用一直在整个目录中搜索了
  • 快表 记录
    • 最近使用地址的映射信息
      • 的高速缓存
    • 从而避免每次访存都要访问页表

如图5-29,TLB

  • 的每标记项存放虚页号的一部分
    • 每数据项中存放了物理页号
  • 由于每次访问TLB而不是页表
    • so TLB需包含其他状态位,如脏和引用

图5-29

  • TLB是页表的CACHE
    • 存放映射到物理页中的那些项
  • TLB包含页表的子集
  • TLB映射灰线表示
  • TLB是个cache,so必须包含标记
  • 如果一个页在TLB无匹配项
    • 就必检查页表
    • 页表要么提供该页的物理页号
      • 可用来创建一个TLB项
    • 或指出该页在磁盘上
      • 这时发生缺页
  • 页表不是cache
    • 不要标记哦

每次访问,在TLB查找虚号

  • 如命中,物理页号用来形成地址
    • 相应的引用位被置位
  • 如果处理器执行是写操作
    • 脏位同样置位
  • if TLB缺失
    • 必须判断是缺页还是TLB缺失
    • 如果该页在主存
      • then TLB缺失只是一次
        • 转换缺失
      • 此情况,处理器可通过将页表中的变换装载到TLB中
      • 且重新访问
      • 来进行缺失处理
    • 若该页不在主存
      • TLB缺失就是真缺页
      • 此情况,处理器调用OS的异常处理
  • 由于TLB中的项比主存中的页数少得多
    • so TLB缺失比缺页频繁的多

TLB缺失既可

    • 也可软
    • 实际上,俩方法性能差很小
    • because 无论哪法,需执行操作一样

下段

  • 在发生了TLB缺失
    • 且已在页表中找到了缺失的变化时
    • 就需从TLB中选择一项进行替换
    • 由于TLB表项包含了引用位和脏位
      • 当替换某一项时
      • 需要把这些位复制回页表项中
      • 这些位是TLB中唯一可修改的部分
  • 写回策略
    • 只在缺失时将这些表项写回
    • 而不是任何写操作都写回
      • 是有效的
      • 因为俺们期望TLB缺失率更低
  • 一些系统用其他技术
    • 近似引用位和脏位
    • 以消除除了缺失后装入新表项
    • 之外写TLB的必要

TLB的一些典型值

  • TLB大小:16-512项
  • 块大小:1-2个页表项(通常每个4-8字节)
  • 命中时间0.5-1个周期
  • 缺失代价:10-100
  • 缺失率:0.01%-1%

TLB设计中相联度设置多样化

  • 有些系统用小的全相联的TLB
    • because 全相联缺失率小哦
    • 且TLB很小,全相联的成本也不大
  • 其他系统用相联度低容量大的TLB
  • 全相联映射方式下
    • 用硬件实现LRU的代价很大
    • 因此,替换项的选择就复杂
  • TLB缺失率比缺页频繁的多
    • 因此要较低的代价来处理缺失
    • 而不可像缺页那样选开销大的软件算法
    • 所以很多系统都支持随机的选择替换表项的算法
  • 5.8详细介绍替换策略

内置FastMATH TLB

  • 进一步研究内置 FASTMATH的TLB。
  • 页大小4KiB,地址空间为32位,
    • 虚页号20位,如图5-30顶部。
  • 物址和虚址长度=。
  • TLB含16项,全相联,指令和数据访问共享。
  • 表项64,
    • 含20位的标记位(虚页号)、
    • 相应的物理页号(20位)、
    • 一个有效位、
    • 一个脏
    • 其他管理操作位。
  • 多数MIPS系统类似,用软件处TLB缺失。

图5-30

FIVE drlhgsd:kfccqccjg_第9张图片

  • 内置FASTMATH中
    • TLB和cache实现从虚址到数据项的转换
  • 本图描述TLB和数据cache的结构,页大小4KiB。
  • 本图研究读,图5-31则描述写。
  • 不同于图5-12,标记和数据RAM是分开的。
  • 用cache索引和块偏移来寻址长而窄的数据RAM,
    • 无需用16:1的多路选择器也能选出块中所需的字。
  • 当cache用直接映射方式时,TLB全相联。
  • 由于需要的项可能在TLB中的任何位置,因全相联需将每个TLB标记都与虚页号比较(参考5.4.2节精解)。
  • 若匹配表项的有效位有效,则TLB命中,
    • 物理页号与页偏移中的位
    • 形成访问cache的索引

图5-30是TLB和一个cache

  • 图5-31说明了处理一次读或写请求的步骤。
  • 当一次TLB缺失时,
    • 硬件把被访问的页号保存在一个特殊寄存器中,并产生一次异常。
  • 异常请求OS软处理。
  • 为找到缺失的页的物理地址,TLB缺失程序用虚拟地址的页号,
    • 以及能指出活跃进程页表起始地址的页表寄存器来检索页表。
  • 通过一系列更新TLB的特殊指令,OS将页表中的物理地址放入TLB中。
  • 设代码和页表项都在指令cache和数据cache中,
    • 一次TLB缺失大概13
    • (5.7.7节讨论MIPSTLB代码)。
  • 若页表项中无有效的物理地址,
    • 就发生一次真的缺页。
  • 硬件保存着被建议替换项的索引,这一项是随机的。

图5-31

FIVE drlhgsd:kfccqccjg_第10张图片

  • 在内置FASTMATH的TLB和 cache中处理读或写直达。
  • TLB命中,物理地址就可用来访cache。
  • 对于读,从存储器中取数时, cache产生命中或缺失,提供数据或者引起阻塞。
  • 对于写,若命中, cache某数据项中的一部分内容将被重写,
    • 若写直达还将数据送到写缓冲区。
    • 写缺失和读缺失相同,只是在数据块从存储器中读出后会被修改。
  • 写回需将cache的写入位置位,
    • 且只有当读或写缺失时,如果被替换的块处于修改状态,
    • 才将整块写入写缓冲
  • TLB中和cache中是相互独立,
    • 但cache中只能发生在TLB中后,这意味数据必须在主存中。
  • TLB缺失和cache缺失之间的联系
    • 将在接下来的例子和本章最后的习题中研究

对于写,

  • 有个额外的情况:须检査TLB中的写访问位。
    • 该位可阻止程序向它仅具有读权限的页中进行写。
  • 如果程序试图写,且写访问位关闭的,则产生异常。
  • 写访问位构成了保护机制的一部分,稍后讨论。

5.7.5 集成虚拟存储器、TLB和cache

  • 虚存系统和cache就像一个层次结构一样工作
    • 只有主存中的数据
    • 才可能在cache中出现
  • OS管理该层次结构
    • 当它决定把某page移到磁盘上时
    • 就在cache中将该页的内容刷新
    • 同时,OS改页表和TLB,
    • 这导致访问该页上的数据都发生缺页

最好情况

  • 虚址由TLB转换成物址
    • 送到cache
    • 找到对应数据
    • 取回给处理器
  • 最坏情况下:
    • 访问存储层次结构的TLB 页表和cache都缺失
  • 下面的例子将详细介绍这种交互作用

例题:存储器层次结构的全部操作

  • 存储器层次结构类似于图5-30
    • 由一个TLB和一个cache组成
  • 一次存储器访问可能遇到3种不同类型的缺失
    • TLB缺失,缺页和cache缺失
    • 共有7个可能性

答案(图5-32)

TLB 页表 cache 可能发生么?若可能,啥情况下发生
缺失 可能,但若TLB命中就不看页表啦!但永远检测不到!
TLB缺失,但在页表中找到表项;重试后在cache里找到数据
TLB缺,但在页表中找到表项,重试后在cache里没找到数据
TLB缺失,随后TLB缺页,重试后再cache里必然找不到
不可能,太简单啦!
不可能,太简单啦!
不可能,页不在主存,数据不允许在cache里!

精解

  • 图5-32假定访cache前,存储器地址都被转换成物址
  • cache是按照物理地址索引且是物理标记的
    • 所有cache的索引和标记都物址
    • 而不是虚
  • 在上面
    • 假定cache命中
    • then访存的时间包括对TLB和cache的访问时间
    • 当然这些访问可流水执行

  • 处理器可用一个完整的或部分虚拟的地址来索引cache
  • 叫虚拟寻址cache
    • 用虚址作标记
    • 按虚址索引
    • 且是虚拟标记的
  • so TLB在正常访问的cache中没用到
    • 就把TLB排除在关键路径之外
    • 减少cache延时
  • 当cache访问缺失时
    • 处理器要把该地址转化成物址以便于
    • 从主存中取出cache块

  • 用虚址访cache时,且进程间共享页(进程用异虚址访同页)时
  • 就maybe有别名存在
    • 就是他妈的一个页里边的同一个字居然在cache里面是两个地方!
  • 一个对象有两名时就产生别名
    • 此情况下,俩虚址对应同一页
    • 这种多义性就产生一问题
      • 一页上面的字可能存在于cache中的两不同位置
      • 每个位置对应不同的虚拟地址
  • 导致一个程序写数据,而另一个程序不知道数据已改变
    • 因为咱俩在cache是不同地方!
  • 完全虚拟寻址的cache
    • 要么对cache和TLB的设计进行限制以减少别名
    • 要么需要OS
    • 要么用户
    • 来采取措施以保证别名不发生

  • 这俩个设计观点的折中是用虚址索引的cache————(有时仅用地址的page offset部分)
  • 由于没有被转换
    • 因此实际上是物理地址-----但使用物理标记
  • 这些采用虚拟地址和物理标记的设计
    • 试图同时拥有虚址索引cache的优越性能
    • 以及物理寻址的简单结构
    • 这样就没有别名的问题
  • 图5-30假定页大小4KiB
    • 但实际上有16KiB
    • 因此内置FastMATH就使用了这方法
    • 要实现此法
      • 必须在最小页大小、cache大小以及相联度间权衡
  • 虚拟寻址cache:
  • 别名:
  • 物理寻址cache:

5.7.6 虚拟存储器中的保护

  • 虚存最重要功能

    • 允许多进程共享一主存,
    • 同时为这些进程和OS提供存储保护。
  • 保护机制须确保:

    • 尽管多进程在共享同一主存,
    • 但一个进程不能写
      • 另一用户进程或
      • OS的地址空间。
  • TLB中的写访问位可防止一个页被改写。

  • 若无这一级保护,病毒更泛滥。

  • 硬件/软件接口

  • 为使OS能保护虛拟存储系统,硬件至少提供下三种能力。

  • 由于前两者都需要虛虚拟机,因此其需求相同。

  • 支持至少两种模式,
  • 并指出当前运行的进程是用户还是操作系统
  • 操作系统进程也称超级用户管理、核心或者主管

  • 提供一部分处理器的状态,
  • 是用户进程可读不可写。
  • 包括指示处理器是处于用户态还是管理态的用户/管理模式位、
    • 页表指针及TLB。
  • OS可通过使用只能
    • 在管理态下可用的特殊指令
    • 对它们进行写

  • 提供能让处理器在用户态和管理态下相互切换
  • 从用户态到管理态的转换
    • 通常由系统调用异常处理完成的,
    • 它用特殊指令(如MIPS中的syscall)
    • 将控制权传到管理代码空间的指定位置。
  • 和其他异常处理一样,
    • 系统调用处的PC的值被保存在EPC,处理器被置于管理态。
  • 从异常中返回至用户模式,
    • 使用异常返回( return from exception)指令,
    • 将重置用户模式,
    • 且跳转到EPC中的地址处。

  • 通过用这些机制
  • 且把页表保存在OS的地址空间中,
  • OS可更改页表,
  • 且阻止用户进程改它们,确保用户进程只能访问由OS提供给它的存储部分。
  • 超级用户管理模式:也称kernel mode。运行OS进程的模式。
  • 系统调用:将控制权从用户转換到管理模式的特殊指令,
    • 触发进程中的一个异常机制。

  • 要防止一进程读取另一进程的数据。
  • 成绩放在处理器的主存中,不希望学生程序读它们。
  • 一旦开始共享主存,必须赋予进程保护数据防止被其他进程读或写的能力;

  • 每个进程有自己的虚拟地址空间。
  • 因此,如果OS管理页表的组织,使独立的虚拟页映射到不相交的物理页上,就能使得一进程无法访问另一进程的数据。
  • 这也要求一个用户进程不能改变页表的映射。
  • 如果OS能防止用户进程更改自己的页表,那么安全性就有保证。
    • OS必须负责修改页表。
    • 将页表放在OS的保护地址空间就OK。

  • 当进程想以受限的方式共享信息时,OS须协助它们,
  • 访问另一进程的信息需要改变访问进程的页表。
    • 写访问位可用来把共享限制为只读,
    • 和页表中其他位一样,该位只能被OS修改。
  • 为许进程P1,去读P2的一页
    • P2就请求OS在P1地址空间中为一个虚拟页生成页表项,指向P2想要共享的物理页。
    • 如果P2要求,OS可用写保护位以防止P1对数据改写。
  • 只有LTB缺失才访问页表,
    • 任何决定页的访问权限的位不仅要含在页表中,
    • 还要含在TLB

精解

  • 当OS决定从P1切到P2时,
    • 须保证P2不能访问Pl的页表,否则不利于数据保护。
  • 若没有TLB,只把页表寄存器转而指向P2的页表(而不是P1的)就OK;
  • 若有TLB,须在其中清除属于Pl的表项
    • 为保护P1的数据,
    • 且为了迫使TLB装入P2的表项。
  • 若进程切换频率高,这一法效率就低。
  • 在OS切回P1前,P2可能只装入了很少的TLB表项。
    • P1随后发现它所有的表项都不见了,不得不通过TLB缺失来重新加载
  • 原因是
    • P1和P2使用同一虚址空间,且必须清除TLB以防止地址混淆。

  • 另一法
  • 通过增加进程标识符和
    • 任务标识符来扩展虚拟地址空间。
    • 内置FASTMATH有8位地址空间标识域(ASID)。
      • 标识当前正在运行的进程;
    • 进程切换时,它保存在由OS装入的寄存器中。
  • 进程标识符与TLB的标记部分相连接,
    • 只有在页号和进程标识符同时匹配TLB才中。
  • 这样的话就不需清除TLB。

  • 同样的问题在cache中发生,进程切换时,cache包含正在执行的进程的数据。

  • 对物理寻址和虚拟寻址的cache来说,问题以不同方式产生,且有不同的解法

  • 如使用进程标识符来确保一个进程只能获得它自己的数据。

  • 上下文切换:为许另一个进程用处理器,改变处理器内部的状态,并保存当前进程返回时需要的状态。

5.7.7 cope TLB缺失和缺页

  • TLB中时,TLB将虚址变物址是easy
  • 但cope with TLB缺失和缺页复杂哦
  • TLB中无一表项匹配虚址时,曰缺失!
    • 页在主存,只需创建缺失的TLB表项
    • 页不在主存,需将控制权交OS来解决缺页

本大佬注:TLB找不到那一个项目,就立刻喊缺失啦!然后从内存中将缺失的那一项读到TLB,然后再重新执行,此时肯定不可能是缺失了,此时主要看是不是缺页了啊!!

有人可能疑惑:为啥不在从内存中将缺失的哪一份读到TLB的时候顺便看看缺页了吗??

  • MIPS常软处缺失
  • 从主存取出页表项装入TLB
    • then重执引起TLB缺失的那指令
    • 此时TLB命中
  • 如果页表说该页不在主存
    • 发生缺页异常

  • 处理TLB缺失or缺页需用异常机制来中断活跃进程
  • 将控制权给OS
    • 然后恢复执行被中断的进程
  • 缺页 在 主存访问时钟周期 的某刻被发现
    • 为在缺页处理后重启引起缺失的那指令
    • 保存该指令的程序计数器中的值
    • 如4章描述,EPC保存该值

  • TLB缺失和缺页异常须在访存发生的同一个时钟周期的末尾被判定
  • so下个szzq就异常处理而不继续指令执行
  • 若这个szzq没断定缺页发生
    • 一条load maybe改写寄存器
    • 而当重启指令时
    • mabe a disaster
  • 例如:
    • lw $1,0($1)
    • 须防止写流水级发生
    • 否则就不能重新执行指令
    • 因为$1的内容将被破坏
    • store也类似
  • 当缺页没有完成处理时
    • 阻止写主存!
    • 常令到主存写控制线无效

在这里插入图片描述

  • OS开始进行异常处理和保存处理器所有状态位时,OS很脆弱。
  • 若在OS中正在处理第一个异常时,另一异常又发生,控制单元将重写EPC,就不能返回引起缺页的那条指令。
    • 通过禁止异常和使能异常避免
  • 当异常第一次发生时,处理器设一个管理态模式位,禁止其他异常发生;
    • 这可与处理器设置管理态模式位同时进行。
  • 随后OS保存足够的状态,若有另一异常发生——EPC和异常引发寄存器也能保存这些状态。
  • EPC和异常引发寄存器
    • 是协助处理异常、TLB缺失及缺页的特殊控制reg;
    • 5-33列出其他的。
  • 而后OS可重新允许异常发生。
  • 这保证异常不会使处理器丢失任何状态,也就不会无法重新执行中断指令。

在这里插入图片描述

FIVE drlhgsd:kfccqccjg_第11张图片

  • 一旦OS知道引起缺页的虚址,它做下三步
  • 用虚址查页表,在磁盘上找到页
    • 查尼玛的老母页表啊,直接看TLB那个不就好了吗
  • 选择替换一个物理页,若被选中的页修改过
    • 把新的虚页装入前
    • 把这个物理页写到磁盘
  • 启动读,
    • 将被访问的页从磁盘上拿到所选择的物理页的位置上
  • 最后一步百万,若被替换的页被重写过,第二步也百万!
  • so OS会选另一进程在处理器上执行until disk access is over
    • 由于OS保存了当前进程状态,
      • so它可方便地将控制权交给另一进程

  • 读页完成后
  • OS恢复原先引起缺页的进程状态
    • 且执行从异常返回的指令(eret)
      • 该指令将处理器从核心态恢复到用户态
        • 同时恢复PC的值
  • 用户进程重新执行引起缺页的那个指令
    • 这下成功访到页

  • 数据访问引起的异常难处理,由于
    • 它发生在指令中间,不同于指令缺失
    • 在异常处理前指令没有结束
    • 异常处理之后,指令必须重新执行,好像啥没发生过

  • 要保持指令 可重启
  • 这样异常被处理之后
    • 指令也能继续执行
    • 这在MIPS的结构中的实现较easy
  • 因为指令只可写一个数据项
    • 且只在指令周期的最后写
    • 我们就可阻止指令的完成(不执行写操作)
    • 且在开始处重启指令

在这里插入图片描述

  • TLB缺失时
  • MIPS硬件将 页号 存在
    • BadVAddr
    • 然后异常

  • 此异常请求OS通过软处理
  • 控制权传到8000 0000
    • TLB的缺失处理程序位置
  • 为找 缺失页的物理地址
  • TLB缺程 用虚页号
    • 和 活动进程的 页表寄存器 检索页表
  • 为快检,MIPS将 所需信息 都放 现场
    • 现场寄存器里面放的就是我这个缺失项在页表里的内存地址啊!!,而且这个项只有一个字,也就是4字节。
    • 高12是页表的基准地址
    • 牛鞭啊,页表的起始地址高12位才算数,后面20位都是0 哈
    • 接着18是缺失页的虚址
    • 12+18=30,难道我找到一个地址才需要30位吗?不应该是32位吗!因为我一项是4字节啊,原来如此!
    • 每个页表项1个字,so最后两位是0
  • 头两条将 现场中的内容copy到内核临时寄存器$k1
    • 根据其中的地址将页表项装入$k1
    • $k1和$k0是为OS保留的不做保存的寄存器
      • 这样使得TLB处理程序执行更快

FIVE drlhgsd:kfccqccjg_第12张图片

在这里插入图片描述

  • MIPS有一组特殊的指令更新TLB
  • tlbwr 把控制寄存器EntryLo 中内容复制到由Random所选择的TLB表项中
  • Random实现随机替换,基本是个独立运行的计数器
  • 大概12szzq

  • 缺程不检查页表项是否有效。
  • 因为TLB表项缺失比缺页频繁得多,所以OS对页表中的表项不检查就直接装入并重执
  • 若表项无效,另个不同的异常就发生,OS认为缺页。
  • 此法让频繁发生的TLB缺失处理得快些,
    • 但对不频繁发生的缺页就会有性损失。
    • 意思就是本来你可以在TLB缺失时,从页表读到TLB的候就发现缺页的,结果你现在才发现!!

  • 一旦产生缺页的进程被中断,控制权就转8000 0180
    • 处理异常的通用地址
  • TLB缺失有专门的入口
    • 是为减少TLB缺失代价
  • OS用异常引发寄判异常原因。
    • 由于是缺页,OS知道需进一步处理。
    • 不同于TLB缺失,它保活动进程的全部状态,
    • 所有的通和浮、页表地址寄、EPC和异常引发寄的状态。
    • 浮寄在异常处理程序不常用,
      • 因此通用入口点没保存它们,
      • 而是留给少数需要它们的处理者。

本大王的疑问:不保留浮点寄存器,那要是切换进程了咋办啊?问题在于这个异常处理程序算不算是“切换进程”呢?我觉得这个异常处理程序还是当前进程的一部分,类似于系统调用吧,也就是在执行这个处理程序到某个需要I/O的地方,被内核切换到别的进程了,待到那个时候内核需要保存全部寄存器状态吧!!

  • 图5-34:异常处理程序
  • 用MIPS代码来保存和恢复状态,
    • 注意何时允许和禁止异常,
    • 调用C处理特殊的异常

本大佬的疑问:这个$sp是这个进程的内核态堆栈指针吗?我觉得是的,因为这个处理程序执行的CPU是管理态的!

mfc0是读控制寄存器到普通的寄存器,因为sw指令没法直接对控制寄存器操作

那啥时候设置它禁止异常的呢!它上文说是设置管理态的时候呢!
那然后到底是设置哪个寄存器来使得它允许异常呢!答案:$sr啊!

设置$gp的目的是啥??

FIVE drlhgsd:kfccqccjg_第13张图片

  • 引发缺失的虚址取决于当前缺失是指缺还是数缺
  • 你麻痹的,你不是说缺失的项的地址都在现场寄存器里吗,我你妈一看看这个地址不就知道了引发缺失的虚拟地址了吗!!!
  • 产生缺失的指址在EPC
  • 若是指令缺页,EPC含缺失页的虚址
  • 否则,缺失页的虚址通过查看指令(指令地址在EPC),
    • 找到基址寄和偏移量计算得到。

意思是如果一条load指令执行的时候缺失了,EPC保存的是这条load指令的地址啊!那么缺失页的虚拟地址还得计算下才能得到啊!切,我看看现场寄存器,找到内存中那个页表项,也可以知道缺失页的虚拟地址呦

在这里插入图片描述

  • 此简化版假设堆栈指针(sp)有效。
  • 避免执行异常代码时缺页,MIPS预留一部分不会产生缺页的地址空间,称unmapped
  • OS将异常入口点代码和异常堆栈放在非映射内存
  • MIPS硬件将虚址8000 0000~ BFFF FFFF换成物址时,把这些地址放在物理内存低位。
  • 因此,OS就将异常入口点和异常堆栈放置于非映射的主存中

在这里插入图片描述

在这里插入图片描述

  • 图5-34:MIPS-32的异常返回序列。
  • 早先MIPS-I架构用rfe和jr代替eret。

在这里插入图片描述

  • 有着更复杂指令的处理器,
    • 会访问主存中的很多位置且写很多数据项,使指令重启更难。
  • 处理一条指令可能在指令中间多次缺页。
    • x86有能访问成百上千数据字的块移动指令。
    • 这样的处理器中,指令无法像在MIPS中那样从起始位置重新启动。
    • 相反,指令必须被中断,稍后从执行中断处继续执行。
  • 在执行的中间恢复一条指令通常需要保存一些特殊状态,处理异常,然后恢复那些特殊状态。
  • 要正确地执行这项工作需要在
    • OS的异常处理代码和硬件中细致协调。

在这里插入图片描述

  • 与每次存储器访问都需一次间接寻址不同,
    • 虚拟机支持一个影子页表(shadow)
    • 用于用户虚拟地址到硬件物理地址转换。
  • 通过检测对用户页表的所有修改,虚拟机可确保
    • 硬件正在用于转换的影子页表表项与用户操作系统中的页表表项一致,
    • 不同的是
    • 在用户页表中使用正确的物理地址替代了实地址。
  • 因此,虚拟机必须在用户操作系统试图改变其页表或访问页表指针时产生自陷。
  • 这通常由用OS通过
    • 对用户页表进行写保护
    • 和对页表指针的任何访问产生自陷来实现。
  • 如前所述,如果是特权操作访问页表指针后会发生后面一种情况。

在这里插入图片描述

  • 体系结构中要虚拟化的最后一部分是I/O。
  • 计算机中I/O设备数量和类型不新増加,I/O虚拟化成了系统虚拟化中最难的
  • 另个难点是多个虚拟机之间共享实际的设备。
  • 还有一个问题是要支持大量的设备驱动程序,这在一个支持多用户OS的虚拟系统上更加严重。
  • 它为每种虚拟机中各种类型的I/0设备提供一个通用的驱动,并且将其留给VMM以管理实际的I/O。

在这里插入图片描述

  • 除要对指令集虚拟外,另个挑战是虚拟存储器的虚拟化
    • 主要是因为每种虚拟机上的OS要维护自己的页表
  • 为使其工作,虚拟机中实存储器和物理存储器是两个不同的概念(这两个概念通常被认为是相同的),
    • 实存储器是位于虚拟存储器和物理存储器之间的一个独立层次。
  • (有人用虚拟、物理和机器来表示相同的三个层次。)用户OS通过其页表将虚拟存储器映射到实存储器,
    • 虚拟机页表将用户实存储器映射到物理,
    • 虚拟存储器体系结构要么如 IBM VM/370和x86一样通过页表实现,
      • 要么如MIPS一样通过TLB实现。

5.7.8 小结

  • 虚拟存储器是
  • 管理主存和磁盘之间数据缓存的一级存储器层次。
  • 虚拟存储器允许单个程序在主存有限的范围内扩展地址空间。
  • 更重要,虚拟存储器以一种保护的方式,同时支持多个活跃的进程共享主存。

  • 管理主存和磁盘间的存储器层次结构很有挑战,
    • 因为缺页代价很高。
  • 常用下面技术降低缺失率
    • 增大页容量以利用空间局部性并降低缺失率。
    • 用页表实现的虚址和物址之间的映射用全相联,
      • 这样虚拟页就可被放置到主存中的任何位置。
    • OS用类似LRU和访问位技术来选择替换哪一页。

  • 写磁盘的代价很高,
  • 虚拟存储器用写回机制
    • 且跟踪是否有一页更改过(脏位)以避免把没变化的页写回磁盘。

  • 虚拟存储器
  • 提供被程序使用的虚址到用来访问主存的物址的转换。
  • 这个地址转换允许对主存进行
    • 受保护的共享,
    • 同时提供了很多额外的好处,如简化存储器分配。
  • 为保证进程间受到保护,
    • 要求只有OS才能改变地址变换,
    • 这是通过防止用户程序更改页表实现。
  • 可以在OS的帮助下实现在进程之间受控制地共享页,
    • 页表中的访问位被用来指出用户程序对页进行读还是写。

  • 如果对于每一次访问,处理器不得不访问主存中的页表来进行转换,这样虚拟存储器的开销将很大, cache也将失去意义。
  • 相反,对于页表,TLB扮演了地址转换cache的角色,
  • 利用TLB中的变换,将虚址转换为物址。

  • cache、虚拟存储器以及TLB
  • 都建立在一组共同的原理和策略基础上。
  • 下一节讨论这个共同的架构。

  • 虚拟存储器能使一个小容量的存储器看起来像大容量,但二级存储器和主存之间的性能差异意味,
  • 如果一程序经常访问比它拥有的物理存储器多的虚拟存储器,程序运行速度就很慢。
  • 程序会不断地在存储器和磁盘之间交换页面,称thrashing。
  • 抖动是灾难,但很少见。
  • 你程序产生抖动,
    • 让你程序在一个有着更大存储器的计算机上,
    • 或为你的计算机加存储器。
  • 复杂办法是检查用的算法和数据结构,
    • 改变它的局部性,
    • 减少程序同时使用的页数。
    • 这一组页通常被称working set

  • 更常见的性能问题TLB缺失。
  • TLB同时只能处理32-64页表项,程序很容易会有较高的TLB缺失率,处理器只能直接访问64×4KiB=0.25MiB。
  • 对基数排序,TLB缺失通常是个挑战。
  • 为缓解,现在很多体系结构支持可变的页大小。
  • 除4KiB标准页面,MIPS硬件还支持16、64、256、IMiB、4MiB、16MiB、64MiB和256MiB页面。
  • 如果一个程序用大容量的页面,就能直接访问更多主存不会有TLB缺失。

  • 令OS允许程序选择这些大容量的页面也是实际难题。
  • 减少TLB缺失复杂方法是重新检査算法和数据结构以减少页面工作集;
  • 存储器访问对于性能以及TLB缺失频率至关重要,
    • 所以一些工作集较大的程序已经在这方面做重新设计。

FIVE drlhgsd:kfccqccjg_第14张图片

这儿额!!!!!!!!

5.10 并行与存储器层次结构: cache一致性

  • 单芯片上有多处理器,共享公共的物理地址空间。
  • 两个不同的处理器所保存的存储器视图
    • 通过各自的cache得到,
    • 两个处理器可能得到两个不同的值。
  • 图5-41说明两个不同的处理器对存储器相同位置操作会得到不同的值。
    • 称cache一致性问题。

FIVE drlhgsd:kfccqccjg_第15张图片

  • A和B对同一个存储器位置X读写。
  • 最初两cache都不含该变量且X为0。
  • 写直达cache;
    • 写回 cache则带来额外的更复杂。
  • 当X值被A改后,A的cache和存储器中的副本都做更新,
  • 但B cache没有,如果B读X,得到0

  • 如果在一个存储器中读任何一个数据项的返回结果总是最近写入的
    • 则该存储器有一致性。
    • 这个定义尽管看起来正确,但仍模糊且简单;
    • 实际情况复杂得多。
  • 这个简单定义包括存储器系统行为的两不同方面,它们对于编写正确的共享存储程序是至关重要的。
  • 第一方面coherence,它定义读操作可以返回什么样的数值。
  • 第二方面consistency,它定义了写入的数据什么时候才能被读操作返回。

  • 先看一致性。
  • 如果存储系统满足如下,就认为该存储系统是一致的
  • 1)P对位置X的写后紧跟P对X的读,且在这次读和写之间没有其他处理器对X写,这时读总返P写入值。图5-41,如果 A在时间3之后读X,它得到1。
  • 2)在其他处理器对X的写后,P对X执行读,这两个操作之间有足够的间隔且没有其他处理器对X写,这时读返回的是写入值。图5-41需一机制,以便在时间3,CPUA向存储器地址X写入数据1之后,B的cache中的数值0被数值1替换。
  • 3)对同一个地址的写是串行执行的;任何两个处理器对同一个地址的两个写在所有处理器看来都有相同的顺序。如果时间3后,B又向存储器地址X中写人2,那么处理器绝不会从该地址中先读出2再读出1

  • 第一个性质保证程序的顺序
    • 即使在单处理器中也要保证这个性质。
  • 第二个性质定义了存储器的一致性意味着什么:
    • 如果一个处理器总是读到旧的数值,我们就认为这个存储器是非一致性的。

  • 假如没将写操作串行化,P1写地址X后,紧跟P2也写X。
  • 写操作串行化保证每个处理器都在某时间看到P2写入结果。
  • 如果没将写操作串行化,就出现一些处理器先看到P2写结果再看到P1写结果,从而可能保留P1写的值。
    • 最简单方法
    • 是保证对同一个地址的写操作在所有处理器看来都具有相同的顺序,这个性质称写串行化

5.10.1 实现一致性的基本方案

  • 支持cache一致性的多处理器中,

    • cache提供共享数据的迁移 复制
  • 迁移:数据项可移入本地cache并以透明的方式使用。迁移减少访问远程共享数据项的延迟,且减少对共享存储器带宽的需求。

  • 复制:当共享数据被同时读取时,cache在本地对数据项做备份。复制减少访问延迟和读取共享数据时的竞争。

  • 迁移和复制的支持对访问共享数据的性能来说重要,许多多处理器引入硬件协议来维护cache一致性。
  • 称 cache coherence protocol。
  • 实现的关键:跟踪所有共享数据块的状态。

  • 最常用的snooping协议。
  • 每个含物理存储器中数据块副本的cache还要保留该数据块共享状态的副本,但并不集中地保存状态。
  • cache通过广播媒介(总线或网络)访问,所有的 cache控制器对媒介监视或监听,来确定它们是否含有总线或交换机上请求的数据块副本。

  • 后面章节介绍用共享总线实现
    • 基于监听的cache一致性,
    • 任何可向所有处理器广播cache缺失的通信媒介都可用来实现基于监听的一致性机制。
  • 向所有cache广播的方法使监听协议的实现简单,也限制了其可扩展性。

5.10.2监听协议

  • 实现一致性的一种方法:处理器写数据前,保证该处理器能独占该数据项。
  • 称写无效协议,因为它在写时令其他副本无效。
  • 独占访问确保写操作执行时不存在其他可读或可写的数据项副本: cache中该数据项的其他所有副本都无效。

  • 图5-42:基于监听总线的写无效协议的例子,cache用写回。
  • 写后紧跟其他处理器执行读:由于写要独占访问,执行读的处理器中保存的任何副本被置无效。
  • 读时,cache缺失,cache需取回新的数据副本。
  • 对写,要求执行写的处理器可独占访问,以防止其他处理器同时执行写。
  • 两个处理器同时对同一个数据写,一个在竞争中获胜,另一个处理器的副本置无效。
  • 竟争失败的处理器要完成写,就必须取得新数据副本,这个副本中已包含更新后的数据。
  • 因此这个协议也强制了写操作的串行化

FIVE drlhgsd:kfccqccjg_第16张图片

  • CPU和X的存储器内容是处理器和总线动作都完成后的数值。
  • 空格表没有动作或没存放副本。
  • B第二次缺失时,CPU A回应,同时取消来自存储器的响应。
  • 随后B的 cache和X的存储器内容都得到更新。
  • 这种当块共享时对存储器进行更新的方法简化了协议,但可能只有当块被替换时才有跟踪所有权并强制写回。
  • 这就需引入一个被称为“所有者”的额外状态,它表明块可被共享,但当块被改变或替换时,由所有者处理器负责更新其他处理器和存储器

  • 块大小对cache一致性起重要作用。
  • 以对一个cache监听为例, 块大小8字,两个处理器可以对块中的一个字进行读/写操作。
  • 多数协议会在两个处理器之间交换整个块,因此増加了所需的一致性带宽。
  • 大的块同样引假共享:
  • 当两个不相关的共享变量存在相同的cache块中时,尽管毎个处理器访问的是不同的变量,但是在处理器之间还是将整个块进行交换。
  • 因此,程序员和编译器需要谨慎放置数据以避免发生假共享。

5.15谬误和陷阱

  • 作为计算体系结构中的定量原则,存储器层次结构似乎不易受到谬误和陷阱的影响。
    • 实际上不然
  • 下面以经常遇到的陷阱开始讲解。

陷阱:写程序或编译器生成代码时忽略存储系统的行为。

  • 谬误:“在写代码时,程序员可以忽略存储器层次”。
  • 图5-19中的排序和5.14节的cache分块技术证明
  • 若程序员设计算法时考虑存储系统的行为,则很容易性能翻倍。

陷阱:模拟cache时,忘记说明字节编址或cache块大小

模拟cache时(手动或者通过计算机),

  • 须保证,确定一个地址被映射到哪个cache块时,要说明字节编址和多字块的影响。
  • 有一个容量为32字节的直接映射的cache,块大小为4字节,
    • 字节地址36是块地址9,而(9mod8)=1。
  • 若36是字地址,就映射到块(36md8)=4。
  • 要保证清楚地说明基准地址。

同样须说明块大小。

  • 有个256字节大小的cache,块32字节。

  • 那么字节地址300将落入哪一块中?

  • 将地址300划分成域,就能看到答案
    FIVE drlhgsd:kfccqccjg_第17张图片

  • 字节地址300是块地址
    [ 300 / 32 ] = 9 [300/32]=9 [300/32]=9

  • cache中的块数是
    [ 256 / 32 ] = 8 [256/32]=8 [256/32]=8

  • 块号9对应于 cache块号(9mod8)=1

包括作者(在早期的书稿中)

  • 和那些忘记自己预期的地址是字、字节或块号的教师们,都犯过这个错误。

陷阱:对于共享 cache,组相联度少于核的数量或者共享该 cache的线程数。

  • 若不特别注意,运行在 2 n 2^n 2n个处理器或线程上的并行程序
    • 为数据结构分配的地址可能映射到共享二级cache同组中。
  • 若cache至少是 2 n 2^n 2n路组相联,那么通过硬件可以隐藏这些程序偶尔发生的冲突。
  • 如不是,程序员可能要面对明显不可思议的性能缺陷
    • 事实上是由于二级 cache冲突缺失引起的————在程序迁移时发生,
    • 假定从一个16核迁移到一个32核上,且如果它们都使用16路组相联的二级cache。

阱:用存储器平均访问时间来评估乱序处理器的存储器层次结构。

若处理器在cache缺失时阻塞,那么你可以分别计算存储器阻塞时间和处理器执行时间,因此可以使用存储器平均访问时间来独立地评估存储器层次结构(见5.4节第2例)。

如果处理器在cache缺失时继续执行指令,甚至可能维持更多的cache缺失,

  • 则唯一可用来准确评估存储器层次结构的办法是
    • 模拟乱序处理器和存储器结构。

这儿额!!!!!!!!

5.18练习题

5.1

  • 考虑矩阵计算中存储器的局部特性。
  • 代码由C编,
    • 同一行中元素被连续存放。
    • 每个字32位整。
      FIVE drlhgsd:kfccqccjg_第18张图片

5.1.1

  • 16字节cache块可存放多少32位的整?
  • 16/4=4

5.1.2

  • 访问哪些变量显示时局?
  • 就是现在访问了他,等一下又访问他了
  • 显然是i,j
  • 我觉得还有B[i][0]

5.1.3

  • 访问哪些变量显示出空局
  • 只能是A[i][j]

局部性受访问顺序和数据存放位置的影响。

  • Matlab数组是列存储
    FIVE drlhgsd:kfccqccjg_第19张图片

5.1.4

  • 存全部将被访问的32位矩阵元素
    • 要多少16字节的 cache块?
  • 应该是这儿有疑惑

5.1.5

  • 访哪些变量显示时局
  • i,j
  • 我觉得还应该有B[I][0]

5.1.6

  • 访哪些变量显示空局
  • A[j][i]

5.2

  • 32位存储器地址引用的列表,字地址。
    3,180,43,2,191,88,190,14,181,44,186,253

5.2.1

  • 直接映射cache,
  • 16个块,块大小1个字。
  • 每次访问,请标识二进制地址、标记以及索引。
  • cache最开始为空,列出每次访问中还是缺。
  • 0000 0000 0000 0000 0000 0000 00|00 11|00

    • index=0011=3
    • tag= 0
  • 0000 0000 0000 0000 0000 0010 11|01 00|00

    • index=0100=4
    • tag=1011=11
  • 0000 0000 0000 0000 0000 0000 10|10 11|00

    • index=1011=11
    • tag=2
      下面在写纯粹浪费time

5.2.2

  • 直接映射,8个块,块大小2个字。
  • 对每次访问,标识出进制地址、标记以及索引。
  • cache最开始为空,那么请列出每次访问是命中还是缺失。
  • 0000 0000 0000 0000 0000 0000 00|00 1|100

    • index=001=1
    • tag= 0
  • 0000 0000 0000 0000 0000 0010 11|01 0|000

    • index=010=2
    • tag=1011=11
  • 0000 0000 0000 0000 0000 0000 10|10 1|100

    • index=101=5
    • tag=2
      下面在写纯粹浪费time

这儿还有点没写

你可能感兴趣的:(co,and,d)