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

条件指令(cmov)和跳转指令之间的差异[重复]

刘兴修
2023-03-14

我不知道在哪里使用cmov指令,在哪里使用汇编中的跳转instructions?

从性能来看:

  • 它们有什么区别?
  • 哪一个更好?

如果可能的话,请举例说明它们的区别。

共有1个答案

金成济
2023-03-14

movcc是一种所谓的谓词指令。这就是“这个指令在条件(谓词)下执行”的妙语。

许多处理器(包括 x86)在执行算术运算(尤其是比较指令)后,会设置条件代码位以指示运算结果的状态。

条件跳转指令检查条件码位的状态,如果为真,则跳转到指定的目标。

因为跳转是有条件的,并且处理器通常有一个深管道,所以当CPU遇到jmp指令时,条件代码位可能根本没有准备好让jmp指令处理。芯片设计者可以简单地等待流水线耗尽(通常是许多时钟周期),然后执行jmp,但这会使处理器变慢。

相反,大多数人选择使用分支预测算法,它可以预测条件跳转的方向。然后,处理器可以提取、解码和执行预测的分支(或不提取),并继续快速执行,但前提是,如果最终到达的条件代码位对于条件(分支预测失误)来说是错误的,处理器将撤消分支后所做的所有工作,并重新执行沿另一条路径运行的程序。

对于流水线执行来说,条件转移比普通的数据依赖更加困难,因为它们可以改变流经流水线的指令流中的下一条指令。这称为控制依赖,与数据依赖相对(像< code>add一样,两个输入都是其他最近指令的输出)。

分支预测因子非常好,因为大多数分支往往对其方向有偏差。(通常,大多数循环末尾的分支将分支回顶部)。因此,大多数时候,处理器不必退出错误预测的工作。

如果分支的方向是高度不可预测的,那么处理器将有50%的时间猜错,因此不得不退出工作。那很贵。

好吧,现在人们经常会发现这样的代码:

  cmp   ...
  jcc   $
  mov   register1, register2
$: ; continue here
  ...
  ; use register1

如果分支预测器猜对了,这个代码很快,不管分支走哪条路。如果它猜错了很多……哎哟。

因此,条件移动指令。这是一种根据条件代码位有条件地移动数据的移动。我们可以改写上面的内容:

  cmp   ...
  movcc  register1, register2
$: ; continue here
  ...
  ; use register1

现在我们没有分支指令,因此没有使处理器撤消所有工作的预测失误。由于不存在控制依赖关系,无论movcc的行为是否类似于mov register1的条件和推测性执行指令。(您可以用这种方式构建CPU,但这会违背 movcc的目的。)

movcc控制依赖项转换为数据依赖项。CPU将其视为3输入数学指令,输入为EFLAGS及其两个“常规”输入(est寄存器和源寄存器或内存)。在x86上,adccmovae(mov ifCF==0)在无序执行如何跟踪依赖项方面完全相同:输入为CF,两个GP寄存器。输出为目标寄存器。

对于 x86,每个条件组合都有厘米、jccsetcc 指令(setcc 根据条件将目标设置为 0 或 1。因此,它对标志具有数据依赖性,而没有其他输入依赖关系。

 类似资料:
  • 问题内容: 在指令内部创建 隔离作用域 使我们可以将 外部作用域 映射到 内部作用域 。我们已经看到了六种映射到属性的不同方法: = attr &attr @attr = 和 @ 这些作用域映射选项分别做什么? 问题答案: 这可能会造成混淆,但是希望有一个简单的示例可以阐明这一点。首先,让我们将模型绑定与行为分开。 这是一个小提琴,应该有助于将它们联系在一起:http : //jsfiddle.n

  • 这与这个问题有关 想想看,在现代英特尔中央处理器上,证券交易委员会阶段是在微码中实现的,这意味着将有一个检查,通过该检查,一个烧毁的密钥被用来验证PEI ACM上的签名。如果它不匹配,那么它需要做一些事情,如果它匹配,它需要做其他事情。鉴于这是作为MSROM过程实现的,必须有一种分支方式,但鉴于MSROM指令没有RIP。 通常,当分支误预测为被采用时,则当指令失效时,ROB将检查异常代码,并因此将

  • 2、条件转移指令(Transfer Conditionally) 条件转移指令是一组极其重要的转移指令,它根据标志寄存器中的一个(或多个)标志位来决定是否需要转移,这就为实现多功能程序提供了必要的手段。微机的指令系统提供了丰富的条件转移指令来满足各种不同的转移需要,在编程序时,要对它们灵活运用。 条件转移指令又分三大类:基于无符号数的条件转移指令、基于有符号数的条件转移指令和基于特殊算术标志位的条

  • 在分析我的代码时,我发现很大一部分时间(~5%)花在跳转指令上;特别是< code>jnbe 0x1800...。不幸的是,我不确定为什么跳转指令会花费这么多时间(比之前调用相同次数的< code>mulsd命令花费的时间百分比更高);它只是告诉处理器移动到一个特定的位置,实际上它本身并不做任何事情,对吗?我的最佳猜测是,对于这个特定的条件,分支预测失败了,这导致这个语句比我预期的要长。

  • 我正在实现一个表,该表有一个数据类型为的列,我正在尝试了解使用什么索引更好? GIN还是GiST? 在这里查看postgres文档时,我似乎了解到: > GiST更新和建立索引的速度更快,但不如gin准确。 GIN更新和构建索引的速度较慢,但更准确。 好吧,那么为什么会有人想要一个gist索引字段而不是杜松子酒呢?如果gist会给你错误的结果?这一定有一些优势(外部性能)。 谁能用外行的话解释一下

  • 本文向大家介绍CALL和JUMP指令之间的区别,包括了CALL和JUMP指令之间的区别的使用技巧和注意事项,需要的朋友参考一下 在本节中,我们将看到CALL和JUMP指令之间的区别是什么。CALL指令用于调用子例程,但是JUMP指令更新程序计数器值并指向程序内部的另一个位置。 现在让我们看一下CALL和JUMP指令之间的一些详细区别。 跳指令 通话指令 通过使用JUMP,程序控制转移到一个位置,该