指令级并行

Posted yizui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指令级并行相关的知识,希望对你有一定的参考价值。

基于《计算机体系结构:量化研究方法》第3章 指令级并行及其开发

本章内容主要面向计算机设计人员和编译器开发者,因此只记录一些感兴趣的点。

介绍

指令级并行(ILP)就是多条指令同时执行,达到提升性能的目的。因为执行一条指令可以分为多个操作(取码、译码、执行等),所以可以通过流水线模式做到ILP。

每个操作都是独立的功能单元来处理

指令相关性

指令之间可能存在相关性,即后面的指令需要等待前面的指令完成,这会导致流水线停顿。
有以下几种相关

  • 数据相关:当前指令的输出数据是后面指令的输入数据
  • 名称相关:数据无关的指令使用了相同的寄存器或存储器地址。通过寄存器重命名可以规避名称相关
  • 控制相关:分支块里的指令依赖于分支控制指令的结果

乱序执行

当出现相关指令时,可以通过重排序,将无关的指令提前执行(乱序执行),避免流水线停顿。
重排序可以是

  • 硬件层的乱序执行单元
  • 编译器在编译时调整指令顺序,有必要时可以展开循环增加指令,更便于得到充分并行的指令。

重排序需要注意规避以下三种数据风险

  • RAW(写后读):指令j试图在指令i写入一个位置之前读取数据,此时指令j读取到旧值
  • WAW(写后写):指令j试图在指令i写入一个位置之前写入数据,此时最终数据为指令i写入的数据。
  • WAR(读后写):指令j试图在指令i读取一个位置之前写入数据,此时指令i读取到错误的新值。

此外如果是控制相关的话,重排序还需要遵循以下两个约束

  • 如果指令与分支控制相关,则不能移动到分支控制前,使该指令脱离分支控制
  • 如果指令与分支控制无关,则不能移动到分支控制后,使该指令受分支控制

精确异常

当指令执行出现异常时,需要回退该指令之后的指令执行结果。乱序执行时,后续指令的结果可能已经写入寄存器或存储器,回退成本很高,因此就有了重排序缓存。乱序执行的指令执行结束后会先保存在重排序缓存中,最后顺序提交。当出现异常时,不提交即可,做到精确异常

分支预测

当存在控制相关的指令时,如果发生跳转,那么流水线中的后续指令可能都会失效,这会导致严重的性能损耗。为了解决这问题,就有了分支预测。

结语

很多优化其实都是由编译器完成的,对于像我这种级别的程序员来说,就是知道

  • 要使用内存栅栏,保证程序结果不受乱序执行的影响。
  • 可以使用GNU扩展的__builtin_expect()函数来增加分支预测的准确率。

以上是关于指令级并行的主要内容,如果未能解决你的问题,请参考以下文章

指令级并行

指令级并行与 SIMD

指令级并行探索

NVIDIA GPU 上的指令级并行 (ILP) 和乱序执行

体系结构复习2——指令级并行(分支预測和VLIW)

计算机系统结构的基础知识