c - CMP+JE 是否比单个 MUL 消耗更多的时钟周期?

标签 c performance optimization assembly x86

我运行的是 x86 处理器,但我认为我的问题很笼统。我很好奇 CMP + JE 序列与单个 MUL 操作所消耗的时钟周期的理论差异。

在 C 伪代码中:

unsigned foo = 1;    /* must be 0 or 1 */
unsigned num = 0;

/* Method 1: CMP + JE*/
if(foo == 1){
    num = 5;
}

/* Method 2: MUL */
num = foo*5;    /* num = 0 if foo = 0 */

不要深入研究伪代码,它纯粹是为了阐明这两种方法背后的数学逻辑。

我实际上比较的是以下两个指令序列:

方法一:CMP + JE

    MOV EAX, 1    ; FOO = 1 here, but can be set to 0
    MOV EBX, 0    ; NUM = 0

    CMP EAX, 1    ; if(foo == 1)
    JE  SUCCESS   ; enter branch
    JMP FINISH    ; end program

SUCCESS:
    MOV EBX, 5    ; num = 5

FINISH:

方法二:MUL

    MOV EAX, 1    ; FOO = 1 here, but can be set to 0

    MOV ECX, EAX  ; save copy of FOO to ECX
    MUL ECX, 5    ; result = foo*5
    MOV EBX, ECX  ; num = result = foo*5

似乎单个 MUL(总共 4 条指令)比 CMP + JE(总共 6 条指令)更有效,但消耗的时钟周期同样对于指令——即完成一条指令所需的时钟周期数是否与任何其他指令相同?

如果实际消耗的时钟周期取决于机器,那么在大多数处理器上,单个 MUL 是否通常比分支方法更快,因为它需要的指令总数更少?

最佳答案

现代 CPU 性能比仅仅计算每条指令的周期数复杂。您需要(至少)考虑以下所有因素:

  • 分支预测
  • 指令重新排序
  • 注册重命名
  • 指令缓存命中/未命中
  • 数据缓存命中/未命中
  • TLB 未命中/页面错误

所有这些都会受到周围代码的严重影响。

所以基本上,执行这样的微基准测试并获得有用的结果几乎是不可能的!

但是,如果非要我猜的话,我会说没有 JE 的代码通常会更高效,因为它消除了分支,从而简化了分支预测行为。

关于c - CMP+JE 是否比单个 MUL 消耗更多的时钟周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16821739/

相关文章:

c - fgets + 标准输入 : Is it possible to skip first 2 characters?

python - Scikit-Learn 或其他用于参数优化的 Python 工具

c - 将 C++ lambda 传递给旧的 C 函数指针

c - 为什么我不能在 Linux 上通过 execvp() 将 killall 与赋予子进程的新名称一起使用?

objective-c - 加速ios功能

wpf - 在DataGrid中绘制的快速轻量级方法

javascript改变字符串大小写速度

ios - 克服 iPhone 5 系列和 iPhone 4 系列之间的 CPU 功率差异。 iPhone优化

c++ - C 中棘手的符号

MATLAB - 'webread' 由于内容类型检查而变慢?