现代处理器设计——超标量处理器基础(5-8)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shuiliusheng/article/details/82189040

现代处理器设计——超标量处理器基础(5-8)

  1. 重命名中出现的影子寄存器(shadow registers)具有专有用处,例如作为计数寄存器,链接寄存器的重命名等。

  2. 分派阶段停顿的产生原因:寄存器读端口饱和,保留站饱和,重命名缓冲饱和,完成缓冲饱和,多于一条指令分派到同一单元(保留站只有一个写端口),串行化限制

  3. 串行化限制:某些指令要求之前的指令必须在该指令执行之前完成分派/执行,之后的指令必须在该指令执行结束之后才能够分派/执行

  4. MSHR(the miss status holding register):保存cache失效后要处理的操作,直到cache miss处理完成。

  5. 对于分支预测器,16K的一位项的性能要好于8K的两位项

  6. ROB必须要检查给定的IA32指令的边界,确定它们是否严格地遵守原子性规则。(某些微操作被标记为第一个微操作或者是最后一个微操作)

  7. 当对组成IA32指令的一系列微操作进行提交时,不能处理外部的事件,所有外部事件必须等待。当时在两个IA32指令之间,处理器必须能够捕获中断,断点,自陷和处理错误等。

  8. IA32体系结构允许对通用整数寄存器(EAX,AX,AH)进行部分的读取和写入,因此在寄存器重命名实现上就会产生问题。当部分宽度的写操作后面跟有一个更长宽度的读操作时,更长宽度的读操作所需要的数据必须额能够得到前面多个写操作针对寄存器不同部分的更新。

    • 解决:P6的解决方法是由RAT记录整数数组的每一项(对应一个微操作的目的寄存器)所使用的寄存器宽度,为数组的每一项增加一个2位的宽度域,以区分三种宽度的寄存器写操作。RAT使用寄存器的宽度信息来决定当前的读操作是否需要一个比前面写入的值更“宽”的寄存器值。如果需要,RAT必须生成一个部分写停顿。
    • 8位寄存器的独立使用。如果对一个整数寄存器的三种宽度的访问都采用同一个别名,那么会导致大量的假相关出现。使用Low Bank和High Bank,高位字节或低位字节寄存器使用的是不同的重命名表项,两者相互独立的重新命名
  9. 由于RS是乱序分派微操作,其空闲表项典型的分布方式是分散在已经使用或者已经分配的表项之间,所以不能使用正常的循环缓冲模型,取而代之的是一种位图方法,每一个RS表项对应着RS分配池中的一位数据。通过这种方法,这些表项可以在分配池中以任何顺序被移动或者替代。RS的搜索方式是从地址0开始扫描,直到发现空闲表项为止。

  10. 超标量发展时间表
    这里写图片描述

  11. 六种级别的复杂程度的超标量技术

    • 浮点协处理器方式:发射逻辑允许同时发射一条整数指令和一条浮点指令,其它不允许多发射
    • 整数指令和分支指令:允许同时发射整数指令和分支指令
    • 多条整数指令发射
    • 相关的整数指令发射:使用级联或者3输入的ALU来实现相关的整数指令的多发射
    • 支持精确中断的多功能部件:强调精确异常模型,具有复杂的恢复机制,功能部件较多而发射约束较少。完全乱序执行
    • 扩展的乱序执行:按序分派,乱序执行,按序提交
  12. Alpha为底层软件提供了一种特殊模式,称为特权体系结构库(PAL,privileged architecture library)。这些例程具有强制的入口点并且执行的时候不允许中断。尽管它们是由一般的Alpha指令所组成的,但也可以访问隐藏实现的寄存器和指令。

  13. HP的PA-RISC(Precision architecture精确体系结构)是最早的RISC体系结构之一。

  14. 如果处理器执行指令的速率只受限于真数据相关,则称该处理器运行在处理器的极限状态。在程序动态数据流图中,只要指令的操作数就绪,则该指令就被执行,在这种情况下,该处理器则达到了数据流极限。

  15. 给定一个数据流图,可以通过计算数据流图的高度(存在的最长路径的长度)来计算程序执行时间的下限。数据流极限就是这个下限,并且决定了指令执行可获得的最大速率或者ILP。该速率定义为程序中指令的数量除以数据流图的高度

  16. 程序的值局部性:大部分真实程序产生和消耗的值由有限的值集合构成

    • 重用前面指令计算的结果(指令重用)
    • 根据前面一些指令的结果预测将要执行的指令结果(值预测)
      这里写图片描述
  17. 值局部性出现的经验统计场景:

    • 数据冗余:真实程序的输入构成的集合常常是由变动很小的数据构成。例如包含多个0个稀疏矩阵,包含空格的文本文件
    • 错误检测:对不常发生的情况的检测页常常被编译仅负载单元,而这实际上是运行时的常量
    • 程序变量:利用立即数来构造程序常量比从存储器载入程序常量更加有效
    • 分支的计算:为了计算分支的目标地址,例如switch语句,编译器必须产生代码,将分支表的基地址装载入寄存器,该地址常常是运行时的常量
    • 虚函数调用:为了调用虚函数,编译器必须产生代码来装载函数指针,该指针常常是运行时的常量
    • 黏合代码:考虑到可编址能力和链接约定,编译器必须时常产生黏合代码从一个编译单元调用另一个编译单元。这样的代码包含的load指令与数据的地址往往在程序的整个执行过程中保持不变
    • 可编址能力:为了获得非自动存储单元的地址可编址能力,编译器必须从表中装载指令,该指令只有在程序装载后才被初始化并始终保持不变
    • 调用子图的恒等性:函数或者过程总是被固定的且比较小的函数集合调用,同样,函数和过程自身也趋向于调用固定的函数集合,该集合通常比较小。因此动态调用通常在程序调用图中形成恒等的子图。因此,恢复链接寄存器以及其他调用者保存的寄存器中的load指令有很高的值局部性
    • 存储器别名解析:编译器必须对可能存在别名的store指令的处理采用保守策略,它会频繁地产生似乎冗余的load指令来解析这些别名。这些装载很可能表现出某种程序的值局部性
    • 寄存器溢出代码:当编译器使用完所有的寄存器时,便将保持不变的变量写入存储器并重复地从存储器载入
    • 收敛算法:值局部性常常是由程序员要实现的算法所引起的。常见的例子如收敛算法,该算法在一个数据集合上重复执行,直到达到全局收敛。通常,局部收敛会在全局收敛之前出现,导致收敛域中的重复计算。
    • 轮询算法:算法的选择带来值局部性的另一个例子:使用轮询算法替代效率更高的事件驱动算法。轮询算法中,重复检测会引起大量的冗余计算
  18. 非预测的值局部性利用

    • 记忆法:动态地记录复杂计算的结果,并且在所有可能的情况下,通过重用这些结果来避免这些复杂计算。该技术可以由程序员手工执行,也可以由编译器自动执行。缺点:所有被纪录的计算必须保证没有副作用,计算本身必须不改变任何全局状态,也不会依赖于外部对全局状态的修改,并且它的所有的输入必须定义清楚,以便记忆表查找能够符合前面的实例,所有的输出或者对其余程序的影响也必须定义清楚,以便重用机制能够正确执行。
    • 指令重用:记忆法在指令级的硬件实现。这种技术一旦发现“生产者“指令无须执行,则将”生产者“指令和”消费者“指令分离,以发现更多的指令级并行。只要重用机制发现某条指令符合重用历史上的实例,并能够安全使用前一实例的结果,就可以采用这一技术。
  19. 重用历史机制

    • 对于指令重用,要执行的计算由程序计数器来指定,程序计数器在进程地址空间中唯一地指令一条静态指令,而活跃输入则是该静态指令的寄存器和存储器操作数
    • 对于块重用,计算由基本块中指令的地址范围来指令,活跃输入则是基本块入口处活跃的源操作数和存储器操作数
    • 对于trace重用,相应计算和trace cache中的表项相对应,该表项是由取指指令的地址和确定trace控制流通路的一组条件分支的输出唯一确定的,同时也必须指明trace入口处活跃的操作数。
    • 保存在重用缓冲中的前提条件包含一个关键属性,即它们唯一地指令一个事件集合,该集合导致了所纪录结果的计算
  20. 处理器使用重用机制的难点

    • 处理器必须能够忽略重用指令的执行,可以直接执行后面的工作,以此来消除或者减少重用指令所带来的数据相关和结构相关。
    • 重用侯选项必须将它们的结果写入处理器的系统状态,因此需要在现有的物理寄存器文件上再增加写端口
    • 修改指令唤醒和调度逻辑,以便适应延迟实际上为0的重用指令
    • 为了支持精确异常,重用侯选项必须进入处理器的再定序缓冲,同时必须绕过发射队列或者RS,意味着更复杂的控制通路
    • 为了保持正确的存储器引用顺序,需要在处理器的load/store队列中跟踪重用的存储器指令
  21. 数据流区域重用:使用指针嵌入到重用缓冲中来连接具有数据相关的指令。对数据流图而言,因为重用属性可以传递,可以通过遍历这些指针来重用数据流图的整个子图,因此任何指令,只要它的数据流的前项都是重用候选,则它也是重用候选。

  22. 强相关模型:

    • 相关是以一种绝对而精确的方式决定的,即两条指令间的关系不是相关就是非相关,如果存在疑问,认为存在相关
    • 在指令执行中保持相关,即不允许违背相关关系,并且在指令执行过程中,需要保持这种相关
  23. 弱相关模型:

    • 不需要精确确定或者假定相关关系,而是乐观的近似估计甚至暂时忽略相关关系
    • 只要在影响持久的机器状态前能够执行恢复工作,就可以在指令执行中暂时违背相关关系
  24. 弱相关模型的优点:由CFG和DFG指明的程序语义在机器能处理指令之前不需要完全确定,更进一步,只要矫正措施随时可以恢复预测错误,机器就可以主动预测或者暂时违背相关关系。从概念上说,使用弱相关模型的机器有两个相互作用的引擎。前段引擎采用弱相关模型并采用推测执行,后端引擎仍然使用强相关引擎来验证推断的有效性。

  25. 值预测单元:为处理器核心的推断计算产生正确的预测值。值预测单元的效果主要由两个因素决定:准确率和覆盖率。准确性度量预测器能够避免预测发生错误的能力,而覆盖率则度量预测器预测指令输出的能力。准确率和覆盖率一般不可兼得。

  26. 提高预测器准确性:置信度估计技术

    • 置信度估计技术将置信度和每个值预测联系在一起,并使用这些置信度来过滤不正确的预测,以此来提高预测的准确性。如果预测超过某个置信度阈值后,则处理器核心将采用该预测值,否则忽略预测值并不带推测地执行。

    • 置信度是通过历史机制来建立的,该机制在推测正确时使计数器加1,推测不正确时将计数器减1或者重置计数器。
      这里写图片描述

  27. 基于历史的预测器:最简单的基于历史的预测器值只记住特定静态指令最近写入的值,并且推测该指令的下一个动态实例会计算相同的结果。更复杂的预测器提供了相应的方法为每条静态指令存储多个不同的值,然后使用一些策略从这些值中选择一个作为预测值

  28. 计算预测器:试图捕捉一条静态指令产生的值序列的可预测模式,然后计算序列中的下一个实例。与基于历史的预测器的区别在于,能够预测在前面程序执行中没有发生的值。

  29. 预测验证的两个目的:

    • 在预测发生错误的时候能够激发恢复动作
    • 需要将”验证了一个正确的预测“这一事实告诉使用改预测结果进行推断执行的相关指令
  30. 预测错误恢复

    • 利用重新取指进行恢复:硬件改动小,但是代价非常大
    • 利用选择性重新发射进行恢复:选择使用了错误预测值的指令进行重新发射
  31. 数据流主动执行的错误恢复:只要非推测性的操作数就绪,相关指令就将推测性地重新执行,即相关指令存在第二个”影子发射“,就好像前面没有发生推测发射一样。预测验证和第二次发射并行执行,在预测正确的情况下,影子发射将停止,否则影子发射将继续,就像没有发生推测一样执行。问题在于消耗的执行资源太多。

  32. 选择性重发射的问题:

    • 存储器数据相关:要考虑由于使用了预测值进行的得到的预测地址是否会影响其他存储操作,例如定向旁路的问题等
    • 调度逻辑的改变:已经发射的指令可能要被重新发射,所以指令需不需要离开发射队列或者保留站。解决:1.将预测性发射的指令从保留站移除,但是提供额外的机制在需要重新发射的时候将它们重新插入保留站;2. 将它们保留在保留站中直到输入操作数不再是预测的。
  33. 值预测的性能影响因素:

    • 程序或者工作负载中值局部性的程度
    • 正确预测指令和使用结果的指令之间动态相关的距离。如果编译器已经将相关指令调度为距离较远,则好处很少
    • 通过机器模型得到的取指速率。如果取指速率比流水线的执行速率快,则值预测可以显著提高执行吞吐率,否则好处很少
    • 值预测单元获得的覆盖率。越多的指令得到预测,性能好处越多
    • 值预测单元的准确率。
    • 在流水线实现中,发生预测错误后导致的损失。
    • 数据流相关性限制程序的程度。如果程序的性能主要不是受数据相关性的影响,则通过值预测消除数据相关性将不会带来很多好处

猜你喜欢

转载自blog.csdn.net/shuiliusheng/article/details/82189040
今日推荐