当前位置: 首页 > 知识库问答 >
问题:

CMOV是如何提高CPU流水线性能的?

高明辉
2023-03-14

我知道当一个分支很容易预测时,最好使用IF语句,因为分支是完全自由的。我了解到,如果分支不容易预测,那么CMOV会更好。但是,我不太明白如何实现这一点?

问题域肯定还是一样的——我们不知道下一条要执行的指令的地址?因此,我不明白在整个管道中,当执行CMOV时,它是如何帮助指令获取器(过去有10个CPU周期)选择正确的路径并防止管道暂停的?

有人能帮我了解一下CMOV是如何改进分支的吗?

共有2个答案

阙弘博
2023-03-14

有人能帮我了解一下CMOV是如何改进分支的吗?

好吧,它不会改善分支,而是删除它。CMOV可以看作是两个指令合二为一,一个是MOV和一个NOP。执行哪一个取决于标志。所以在内部它可能看起来像

if (cond) {
    mov dst, src
} else {
    nop
}

...

问题域肯定还是一样的——我们不知道下一条要执行的指令的地址?

嗯,不。下一条指令总是CMOV之后的指令,所以指令管道不会失效和重新加载(分支预测和其他优化被搁置一边)。这是一个连续的宏操作码流。下面是一个简单的例子

if (ecx==5)
    eax = TRUE
else
    eax = FALSE

在基本 asm 中:

cmp ecx,5      ; is ecx==5
jne unequal    ; what is the address of the next instruction? conditional branch
mov eax,TRUE   ; possibility one
jmp fin
unequal:       : possibility two
mov eax,FALSE
fin:
nop

和CMOV一起

cmp ecx,5
mov eax, FALSE   ; mov doesn't affect flags
mov ebx, TRUE    ; because CMOV doesn't take immediate src operands, use EBX for alternative
cmove eax, ebx   ; executes as MOV if zero-flag is set, otherwise as NOP
nop              ; always the next instruction, no pipeline stall

在现在的CPU上值得吗?一个明确的是。从我的经验来看,当然也取决于算法,速度的提高是显著的,值得努力。

曹奇文
2023-03-14

CMOV 指令不指示控制流的路径。它们是执行以根据条件代码(即谓词指令)计算结果的指令。一些架构(如ARM)可以根据条件代码预测多种形式的指令,但x86只能执行“mov”,即条件移动(CMOV)。这些被解码,并以延迟执行,以确定指令的结果。

另一方面,分支是可预测的,实际上引导指令的执行。分支预测器“超前看”指令“提取器”,专门查找分支指令,并通过引导流来预测路径。想象一下铁路轨道,前方的人向左或向右移动轨道,告诉火车去哪里。现在,如果这个家伙选择了错误的方向,火车必须停下来,倒车,然后再次朝着正确的方向移动。浪费了很多时间。

另一方面,CMOV并不引导潮流。它们只是简单的指令,需要额外的时间(并产生额外的依赖关系)来根据条件代码找出移动的正确结果。想想火车,不是决定向左还是向右行驶,而是走一条不需要转弯的直线,但速度有点慢(显然要复杂得多,但这是我现在能想到的最好的)。

CMOV过去非常糟糕(延迟非常高),但后来改进得非常快,使其更可用,性能更值得。

希望这能有所帮助…

 类似资料:
  • 我有一个连接到第三方服务并将结果返回给客户端的应用程序。在内部,应用程序向第三方服务发出GET请求并获取结果。我已经使用Reactor和reactive代码在重负载下扩展应用程序。这是一个SpringBoot项目,它运行嵌入式Tomcat并依赖于Web客户端(被动netty向第三方发出请求)。不知何故,CPU利用率和响应时间都比阻塞模式差。硬件设置在Kubernetes中运行单核。 该项目建立在库

  • 我有一个名为Emails的列族,我正在将邮件保存到这个CF中,编写5000封邮件需要100秒。 我使用的是i3处理器,8gb内存。我的数据中心有6个节点,复制因子=2。 我们存储在卡桑德拉中的数据大小会影响性能吗?影响写入性能的所有因素是什么,如何提高性能? 预先感谢..

  • 问题内容: 我在公司中多次设计数据库。为了提高数据库的性能,我只寻找标准化和索引。 如果要求您提高数据库的性能,该数据库包含大约250个表以及一些具有数百万个记录的表,那么您将寻找什么不同的东西? 提前致谢。 问题答案: 优化逻辑设计 逻辑级别是关于查询和表本身的结构。首先尝试最大程度地发挥这一作用。目标是在逻辑级别上访问尽可能少的数据。 拥有最高效的SQL查询 设计支持应用程序需求的逻辑架构(例

  • 问题内容: 我有2张桌子,和。用户可以有很多游戏。我需要所有有人数的人,以及他们的人数(有专栏的)。 附言:我需要将所有数据加载到管理表中。由于游戏太多。我决定对数据进行分页和限制。但是,甚至限制以下查询也需要花费相同的时间。如何更好地查询? 问题答案: 您可以在下面尝试使用表达式

  • 我有一个简单的任务:确定需要多少字节来将某个数字(字节数组长度)编码到字节数组并编码最终值(实现本文:编码长度和值字节)。 最初我写了一个快速完成任务的方法: 这是一段旧代码,编写方式很糟糕。 现在我正在尝试使用按位运算符或类来优化代码。这是按位版本的示例: 以及类的最终实现: 所有方法都按预期工作。我使用秒表类页面中的一个示例来衡量性能。性能测试让我惊讶。我的测试方法执行了1000次该方法的运行

  • 问题内容: 由于我们网站上的大量负载增加,redis现在正努力应对峰值负载,因为redis服务器实例达到100%CPU(在八个内核之一上)导致超时。 我们已将客户端软件更新为ServiceStack V3(来自BookSleeve 1.1.0.4),并将redis服务器升级至2.8.11(来自2.4.x)。我之所以选择ServiceStack,是因为存在使用ServiceStack.Redis 的