V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
amiwrong123
V2EX  ›  程序员

条件传送指令,就比条件转移指令要好吗?

  •  
  •   amiwrong123 · 2022-12-04 18:40:33 +08:00 · 1195 次点击
    这是一个创建于 720 天前的主题,其中的信息可能已经有所发展或是发生改变。

    上图给出了不好的理由,因为转移指令会影响分支预测。(上图来自书籍:x86 从实模式到保护模式)

    但是条件传送指令,也是依赖于标志位来决定是否执行动作的呀(第二段),那岂不是也会影响分支预测啊?

    4 条回复    2022-12-04 19:31:30 +08:00
    geelaw
        1
    geelaw  
       2022-12-04 19:13:53 +08:00 via iPhone
    条件分支需要改变程序计数器并加载不同的指令,条件赋值指令无论指令的效果如何都不改变接下来马上要执行的指令,只会产生数据依赖。

    或者你可以简单地认为条件赋值是某种非常常见且特殊的条件分支,设计成专门的指令是为了让 CPU 从指令级别识别出来这种特殊的条件结构并优化(不可期待 CPU 识别一个条件分支指令的实际效果相当于条件赋值并优化,因为识别这种特殊性需要时间)。
    44670
        2
    44670  
       2022-12-04 19:18:39 +08:00
    您提到的条件传送指令( cmovcc )和条件转移指令( jcc )都是根据标志位来决定是否执行指定的操作的。但是,条件传送指令与条件转移指令在执行方式上是有区别的。

    条件传送指令是通过传送数据来实现条件执行的。如果条件成立,条件传送指令会将指定的数据传送到指定的寄存器中;否则,条件传送指令不会执行任何操作。

    因此,条件传送指令并不会改变程序的流程,所以它并不会影响分支预测。
    ipwx
        3
    ipwx  
       2022-12-04 19:20:29 +08:00
    这本书话没讲完所以楼主有点困惑。
    ----

    首先它说了,条件跳转会影响分支预测。那楼主有没有想过,为啥要分支预测,啥叫分支预测?

    现代 CPU 是流水线结构,同一时间可能有前后一共 20 条指令在并行执行,每个执行每一条指令的不同步骤。对没错,指令是有多个步骤的。这种并行执行指令的不同步骤的做法,叫作流水线。

    想必楼主发现盲点了。对于一个条件跳转指令而言,一共两个分支。那在 20 指令流水线里面,当跳转指令第一次装入这个流水线之后,到底哪个分支应当作为接下来的指令装入流水线?请注意,在跳转指令执行完成之前就必须开始执行接下来的指令了。这里就引入了分支预测,在分支跳转执行完之前就假定接下来是哪个分支被执行,然后开始激进地执行那个分支的接下来 19 条指令。一旦预测错了,那对不起,这 19 条指令的中间结果就会被销毁,重新读取正确分支的指令开始执行。

    如果分支预测错误,就会导致流水线一次失败的提前并行执行,也就是在这一瞬间你的 CPU 慢了 20 倍。如果一个程序的分支预测频繁失败,那你的程序就会慢好几倍。
    ----

    上文中的条件传送,看上去就没有两条分支指令流,只有一条。所以就不存在流水线失败的情况,也就和分支预测没有关系了。
    dazhangpan
        4
    dazhangpan  
       2022-12-04 19:31:30 +08:00
    老夫优化程序 20 年,因为分支预测导致的性能显著下降的案例只在教学示例中遇到过,新一些的处理器( 2 ,3 代至强)分支预测基本上>98%正确率;可以说影响现代计算密集型程序性能的主要因素已不在程序逻辑而在于结构体设计。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2730 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 14:58 · PVG 22:58 · LAX 06:58 · JFK 09:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.