数据依赖与控制依赖的差异



我很难理解数据依赖和控制依赖之间的区别。

所以我看到的例子是:

数据依赖例如,一条指令使用另一条指令

创建的数据。<<p>控制依赖/strong>例如,指令等待更新的reg进行比较

我很难理解的是,例如在beq中,我等待寄存器更新,但我也依赖于他的数据。

所以我不知道如何知道它们之间的区别。

指令wait to updated reg for comparison是对控件依赖关系的错误描述,难怪

条件分支指令本身在检查分支条件之前对其输入寄存器有数据依赖。

指令分支之后对分支有控制依赖。前端需要根据分支是否被占用,知道要获取/解码哪些指令。(或者对于间接分支,目标地址是什么)。

分支预测做出的猜测可能在以后被发现是错误的。(当分支指令实际执行并检查预测时)。

在简单(标量)顺序管道中,从属指令无法在分支指令到达exec阶段之前到达exec阶段。发现并从分支错误预测中恢复只是意味着重新引导前端从正确的地址获取,丢弃从错误路径获取(和解码)的指令。

但是在乱序的执行cpu中可能发生这种情况。特别是如果分支的输入是长依赖链的一部分,但是带有控制依赖的指令没有数据依赖。(也就是说,它们是独立的工作,无序的后端可以推测地开始。)

分支预测+推测执行在预测正确时有效地隐藏了控制依赖项。这就是为什么编译器经常将if (a==0) return a;转换为if (a==0) return 0;或类似的;如果它们无论如何都要进行分支(控制依赖),使用返回值打破/避免代码的数据依赖。

相关:

  • 当skylake CPU错误预测分支时究竟会发生什么?-一个现代的OoO执行CPU。

  • 通过提前计算条件来避免管道停滞-最小化分支本身的数据依赖链的长度,因此它可以提前执行并验证分支预测。

  • 依赖链分析提到了循环分支的控制依赖。

  • CPU预测和内存屏障-投机执行过去的分支可以引入内存重排序。

  • 为什么有条件的移动不容易分支预测失败?- CMOV是一个纯粹的ALU选择操作,只是一个数据依赖,而不是一个控制依赖。

    • gcc优化标志-O3使代码比-O2显示如何CMOV可以更慢,创建一个循环携带的数据依赖链而不是投机执行可以隐藏的控制依赖。

最新更新