跳转到主要内容

3.10 贯穿各层的问题

硬件推测与软件推测

本章高度依赖硬件的推测方法,与附录 H 的软件方法,为开发 ILP 提供了不同选择。它们的部分取舍与局限如下:

  • 要广泛推测,就必须能够对内存访问消歧。对于包含指针的整数程序,在编译时很难做到。硬件方案利用前面介绍的技术,在运行时动态消除内存地址歧义,允许加载在运行时越过存储。支持围绕内存访问进行推测,也有助于克服编译器过度保守的问题;但如果不进行选择性推测,恢复机制的开销可能淹没收益。
  • 当控制流难以预测,而且硬件分支预测优于编译时的软件分支预测时,硬件推测效果更好。许多整数程序符合这些条件:动态预测器的错误预测率通常不到静态预测器的一半。由于预测错误时,推测指令可能拖慢计算,这个差异十分重要。因此,即使静态调度处理器,通常也具有动态分支预测器。
  • 硬件推测即使对推测指令,也能维持完全精确的异常模型。近期软件方案也增加了特殊支持,以实现这一点。
  • 硬件推测不需要补偿或记账代码,而激进的软件推测机制需要这些代码。
  • 编译器能够看到代码序列中更远的部分,可能因此比纯硬件方法获得更好的调度结果。
  • 动态调度结合硬件推测时,为了在同一体系结构的不同实现上取得良好性能,不需要使用不同代码序列。这个优点最难量化,但长期看可能最重要。有趣的是,它也是 IBM 360/91 的设计动机之一。另一方面,IA-64 等较新的显式并行体系结构,也加入了灵活机制,减轻代码序列对具体硬件的固有依赖。

硬件支持推测的主要缺点,是复杂度与额外硬件资源。评价这项成本时,必须同时考虑软件方法的编译器复杂度,以及依赖这种编译器后,处理器可以简化多少、这些简化有多大价值。

有些设计者尝试结合动态与编译器方法,兼取两者之长。但组合也可能产生有趣而隐蔽的相互作用。例如,将条件移动与寄存器重命名结合,会出现一个微妙的副作用:一条被取消的条件移动,仍必须向目标寄存器复制一个值,因为该目标已在流水线较早阶段被重命名。

这些细微交互使设计与验证更复杂,也可能降低性能。

Intel Itanium 是有史以来以软件支持 ILP 和推测为基础、设计目标最为雄心勃勃的计算机。它未实现设计者的期待,尤其是在通用、非科学计算代码上。面对第 244 页描述的困难,设计者开发 ILP 的目标有所收敛,大多数体系结构最终选择硬件机制,每周期发射 3~4 条指令。

推测执行与存储系统

支持推测执行或条件指令的处理器,天然可能产生一些无效地址,而没有推测执行时本不会出现这些地址。

对这些地址触发保护异常,在功能上是不正确的,也很可能抵消推测执行的收益。如 3.5、3.6 节所述,超标量处理器把异常推迟到指令准备提交时,也就是不再具有推测性时才触发。但 3.12 节将看到,即使只是执行了后来会被撤销的无效地址加载,也可能成为严重安全漏洞的根源。

同理,也不能让这些指令因缓存未命中而使缓存停顿,因为不必要的停顿同样可能淹没推测收益。因此,这类处理器必须配备非阻塞缓存。实际上,访问 DRAM 的未命中代价非常大,所以只有当下一级是片上缓存(L2 或 L3)时,才处理推测产生的未命中。

第 84 页的图 2.5 显示,对于某些行为规律的科学计算程序,编译器能够保持多次未完成的 L2 未命中,从而有效降低 L2 未命中代价。要使这种方法奏效,缓存后方的存储系统也必须在同时进行的内存访问数量上,配合编译器的目标。

译注:原文引用“第 84 页的图 2.5”,但本版图 2.5 列出的是 DDR DRAM 与 DIMM 的时钟频率、带宽和命名,不能据此核验本段关于科学计算程序未命中的论述。原引用予以保留,不推断作者本来意指哪个图表。