cmov条件传送指令

cmov条件传送指令

  • 指令介绍

    cmovx 	S,	D
    

    在这里插入图片描述

    1. 条件传送指令集每条指令都有两个操作数:源寄存器或者内存地址S,和目的寄存器R,这些指令的结果取决于条件码的值。源值可以从内存或者源寄存器中读取,但是只有在指定的条件满足时,才会被复制到目的寄存器中
    2. 源和目的的值可以是16位、32位或64位长,不支持单字节的条件传送,汇编器可以从目标寄存器地名字推断出条件传送指令的操作数长度。(这点与无条件的指令有差别,因为无条件指令的操作数显式地编码在指令名中,如movw、movl)
  • Example

    cmp		%rsi,	%rdi
    cmova	%rdx,	%rax	
    

    这个代码片段的含义为:

    如果RDI寄存器中的值大于RSI寄存器中的值,则把RAX寄存器中的值替换为RDX寄存器中的值。

  • 为什么使用条件传送指令会提高性能?

    当机器遇到条件跳转指令的时候,一般都会使用分支预测方法来预测哪个分支会被执行,从而使流水线充满指令,提高效率;但是分支预测不会总是正确的(特别是对于一些诸如x<y不可预测的条件),如果错误预测的话,就需要处理器丢掉之前的工作,从正确位置处的指令开始去填充流水线,这就会浪费很多时钟周期,导致程序性能下降

    而使用条件传送指令,就可以取消“处理器分支预测”这一步,减少控制冒险。

    可以配合下面这个例子进行理解:

    在这里插入图片描述

  • 条件传送指令不会提高性能的情况

    不过因为条件传送指令需要一开始就将两种情况的结果计算出来,当不需要被执行的分支计算量很大时,这样做显然是不划算的。

    在《深入理解计算机系统》这本书中,提到:

    我们对GCC的实验表明,只有当两个表达式都很容易计算时,例如表达式分别都只是一条加法指令,它才会使用条件传送。根据我们的经验,即使许多分支预测错误的开销会超过更复杂的计算,GCC还是会使用条件控制转移。

    我认为这就可能是老师所说的“GCC优化保守”的原因。甚至对于那些有着高分支预测错误率的benchmark(如541leela_r、505mcf_r、557xz_r)如果能更多地使用条件传送指令,可能会进一步提高性能(这只是我的一个猜想,具体还是要根据这些benchmark的源码来下定论)。

  • 不适用条件传送指令的情况

    由于条件传送指令需要将两种情况的结果计算出来,这就有可能会导致问题。如:

    int cread(int* xp)
    {
        return (xp? *xp: 0);
    }
    

    使用条件传送指令时,会分别将“*xp”和“0”放入寄存器,如果xp为NULL时,就会出现空指针引用错误。因此在做这方面优化的时候,一定要注意,两种情况的任意一个都不能出现错误或者副作用。

  • 补充:如何确定分支预测错误的处罚

    在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值