You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x64架构下int/uint64_t对应汇编代码性能差异原因咨询

x64架构下两组汇编代码的性能差异分析

背景与测试代码

对应的原始C++代码如下:

for (int i = 1; i <= number; ++i) {
    if (number % i == 0) {
        std::cout << i << std::endl;
    }
}

第一组汇编是将number和i声明为int时由编译器生成的;第二组则是将二者改为uint64_t(改用int64_t结果一致)时生成的。

测试发现:在11代Intel x64机器上,第一组指令执行速度比第二组快70%;在旧款Ivybridge机器上,第一组甚至比第二组快3倍——哪怕测试时number取的是大32位整数(在第二组中被视为64位类型)。

两组汇编指令对比

第一组(int版本)

mov    ebx, 1
cmp    edi, ebx
jl    SHORT $LN3@main
npad    7

$LL4@main:
mov    eax, edi
cdq
idiv    ebx
test    edx, edx
je    SHORT $LN61@main

$LN2@main:
inc    ebx
cmp    ebx, edi
jle    SHORT $LL4@main

$LN3@main:

第二组(uint64_t/int64_t版本)

mov    ebx, 1
cmp    rbx, rdi
ja    SHORT $LN3@main
npad    4

$LL4@main:
xor    edx, edx
mov    rax, rdi
div    rbx
test    rdx, rdx
je    SHORT $LN61@main

$LN2@main:
inc    rbx
cmp    rbx, rdi
jbe    SHORT $LL4@main

$LN3@main:

性能差异的核心原因

1. 除法指令的硬件效率差距

x86-64 CPU的32位和64位除法指令在硬件层面的执行效率天差地别:

  • 32位的idiv ebx:在Intel酷睿系列(包括11代和Ivybridge)上,延迟通常在10-14个周期,而且除法执行单元的吞吐量较高,每3-4个周期就能启动一次新的除法操作。
  • 64位的div rbx:延迟高达20-40个周期,且吞吐量极低——大部分Intel CPU处理64位除法时,必须等上一次除法完全结束才能启动下一次,没法像32位除法那样并行调度操作。

哪怕测试用的是大32位整数,64位除法指令也会全程按64位宽度执行,完全没法利用32位除法的硬件优化,这是性能差距的核心原因。

2. 寄存器操作的额外开销

第二组使用64位寄存器带来了额外开销:

  • 循环里的inc rbx、cmp rbx, rdi这类操作,在Ivybridge这类旧CPU上,对比32位寄存器操作会有微小的延迟,循环几万次之后差距就被显著放大。
  • 另外,64位无符号除法需要先执行xor edx, edx清空高32位,而32位除法的cdq只是简单扩展符号位,操作更快、延迟更低。

3. 指令对齐的影响

第一组里的npad 7是编译器用来把循环体$LL4@main对齐到16字节边界的填充指令,第二组只做了4字节对齐。更严格的指令对齐能减少CPU取指时的缓存停顿,提升循环执行的流畅度,这点在旧CPU上的影响尤其明显。

内容的提问来源于stack exchange,提问作者arsha_ex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 04:05:15