jig*_*uff 16 performance assembly instructions mov
我很困惑在何处使用cmov说明以及jump在汇编中使用说明的位置?
从性能的角度来看:
如果可能,请通过示例解释他们的不同之处.
Ira*_*ter 16
movcc是一种所谓的谓词指令.这是花哨的 - 说"这条指令在条件(谓词)下执行".
在进行算术运算(尤其是比较指令)之后,许多处理器(包括x86)设置条件代码位以指示操作结果的状态.
条件跳转指令检查条件代码位的状态,如果为真,则跳转到指定的目标.
因为跳转是有条件的,并且处理器通常具有深度流水线,所以当CPU遇到jmp指令时,条件代码位实际上还没有准备好让jmp指令处理.芯片设计人员可以简单地等待管道耗尽(通常是很多时钟周期),然后执行jmp,但这会使处理器变慢.
相反,他们中的大多数人选择使用分支预测算法,该算法预测条件跳转的方式.处理器然后可以获取,解码和执行预测的分支(或不执行),并继续快速执行,条件是如果最终到达的条件代码位对于条件(分支错误预测)而言是错误的,则处理器撤销在分支之后它所做的所有工作,并重新执行沿着另一条路径的程序.
对于流水线执行,条件跳转比普通数据依赖更难,因为它们可以更改流经管道的指令流中的下一条指令.这称为控制依赖,而不是数据依赖(如add两个输入都是其他最近指令的输出).
分支预测变得非常好,因为大多数分支往往偏向于他们的方向.(大多数循环结束时的分支,通常会分支回到顶部).因此,大多数情况下,处理器不必退出错误预测的工作.
如果分支的方向是高度不可预测的,那么处理器将在大约50%的时间内猜错,因此必须退出工作.这太贵了.
好的,现在,人们常常找到这样的代码:
cmp ...
jcc $
mov register1, register2
$: ; continue here
...
; use register1
Run Code Online (Sandbox Code Playgroud)
如果分支预测器猜对了,那么无论分支走哪条,这段代码都很快.如果猜错了很多......哎哟.
因此有条件的移动指令.这是根据条件代码位有条件地移动数据的移动.我们可以改写上面的内容:
cmp ...
movcc register1, register2
$: ; continue here
...
; use register1
Run Code Online (Sandbox Code Playgroud)
现在我们没有分支指令,因此没有错误预测使处理器撤消所有工作.由于没有控制依赖性,因此需要获取和解码以下指令,而不管这些movcc行为是否为a mov或nop.管道可以保持完整而不预测条件并推测性地执行使用的指令register1.(你可以用这种方式构建一个CPU,但它会破坏目的movcc.)
movcc将控件依赖项转换为数据依赖项.CPU将其视为3输入数学指令,输入为EFLAGS及其两个"常规"输入(dest寄存器和源寄存器或存储器).在x86上,adc与cmovae(mov if CF==0)相同,就乱序执行如何跟踪依赖关系而言:输入是CF,以及两个GP寄存器.输出是目标寄存器.
为x86,还有cmovcc,jcc和setcc为每个条件组合立方厘米指令.(setcc根据条件将目标设置为0或1.因此它对标志具有数据依赖性,并且没有其他输入依赖性.)
| 归档时间: |
|
| 查看次数: |
7875 次 |
| 最近记录: |