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

32位与64位寄存器是否会造成CPU微架构层面的性能差异?

寄存器全置1实现的性能测试疑问

我正在对比Peter Cordes在「将CPU寄存器所有位设置为1」相关问题回答中提到的实现方法,为此编写了基准测试程序,将除e/rsp、e/rbp、e/rcx外的13个寄存器全部置为全1。
测试代码如下,times 32 nop用于避免DSB和LSD的影响:

mov ecx, 100000000
Align 32
.test3:
    times 32 nop
    mov rax,-1
    mov rbx,-1
    ;mov ecx,-1
    mov rdx,-1
    mov rdi,-1
    mov rsi,-1
    mov r8,-1
    mov r9,-1
    mov r10,-1
    mov r11,-1
    mov r12,-1
    mov r13,-1
    mov r14,-1
    mov r15,-1

    dec ecx
    jge .test3
    jmp .out

我测试了他提到的以下几种实现方案:

mov e/rax, -1                   

xor eax, eax        
dec e/rax               

xor ecx, ecx        
lea e/rax, [rcx-1]  

or e/rax, -1            

为简化表述,下文表格中使用group1 a (g1a)代指mov eax,-1,分组对应关系如下:

序号指令模式测试编号
group1 amov eax,-1test 7
group1 bmov rax,-1test3
group2 axor eax, eax / dec eaxtest6
group2 bxor eax, eax / dec raxtest2
group3 axor ecx, ecx / lea eax, [rcx-1]test0
group3 bxor ecx, ecx / lea rax, [rcx-1]test-1(test00)
group4 aor eax,-1test5
group4 bor rax,-1test1

测试结果显示,第1到3组使用64位寄存器时,单次循环多消耗1个周期,IDQ_UOPS_NOT_DELIVERED指标也同步上升,请问这是否能精准解释单循环多1周期的现象?测试性能指标如下:

周期数MITE cycles(r1002479)MITE 4uops cycles (r4002479)IDQ UOPS NOT DELIVERED(r19c)
g1a1,300,903,7051,300,104,496800,055,137601,487,115
g1b1,400,852,9311,400,092,325800,049,3131,001,524,712
g2a1,600,920,1561,600,113,4801,300,061,359501,522,554
g2b1,700,834,7691,700,108,6881,300,057,576901,467,008
g3a1,701,971,4251,700,093,2981,300,111,482902,327,493
g3b1,800,891,8611,800,110,0961,300,059,3381,301,497,001
g4a1,201,164,2081,200,122,2751,100,049,081201,592,292
g4b1,200,553,5771,200,074,4221,100,031,729200,772,985

除此之外,g2a和g2b的执行端口分布存在差异,和g1组、g3组的表现不同(g1、g3组的32位/64位版本端口分布一致)。且注释掉times 32 nop后该差异现象消失,请问该现象是否和MITE有关?执行端口分布数据如下:

p0p1p2p3p4p5p6p7
g1a299,868,019300,014,6575,9257,79416,589300,279,232499,885,2947,242
g1b299,935,968300,085,0896,6228,75818,842299,935,445500,426,4367,336
g2a299,800,192299,758,4607,4619,63520,622399,836,486400,312,3548,446
g2b200,047,079200,203,0267,8999,96721,539500,542,313500,296,0349,635
g3a36,568550,860,7737,78410,14722,538749,063,08299,856,6239,767
g3b36,858599,960,1978,23210,76323,086700,499,893100,078,3689,513
g4a200,142,036300,600,5355,3836,70515,344400,045,302500,364,3776,802
g4b200,224,703300,284,6095,4647,03115,817400,047,050499,467,5466,746

测试环境:Intel i7-10700、Ubuntu 20.04、NASM 2.14.02。


问题解答

1. IDQ_UOPS_NOT_DELIVERED上升是否能解释单循环多1周期的现象

可以完全对应。你使用的10代酷睿(Comet Lake)的前端legacy解码通路(MITE)单周期最多只能输出4个uop,你添加32个nop的操作已经屏蔽了DSB(解码缓存)和LSD(循环流检测器),所有指令都走MITE实时解码。
1~3组的64位指令比32位多了1个REX前缀,单条指令长度从5字节变成7字节,13条置1指令合计多了26字节。MITE的取指窗口是16字节对齐,64位版本的指令流会跨更多取指窗口,导致每个循环刚好少传递4个uop,1亿次循环累计的IDQ_UOPS_NOT_DELIVERED增量刚好在4亿左右,和单循环多1周期的损耗完全匹配。
group4的or指令没有出现该差异,是因为or reg, imm的微架构解码优先级更高,长度差带来的取指压力被前端缓冲完全消化,没有出现uop供给不足的情况。

2. g2端口分布差异是否和MITE有关

确实和MITE直接相关。你添加32个nop后,整个循环的指令流对齐状态发生变化,MITE在解码xor-zero + dec的双指令序列时,会根据指令对齐状态给uop打上端口调度偏向标记。xor-zero和dec都可以在p0/p1/p5/p6四个端口执行,解码阶段的调度偏向会直接影响最终的端口分布。
当你去掉times 32 nop后,循环体积足够小,会被DSB或者LSD缓存,此时uop的端口分配由后端统一调度,不会受解码阶段的对齐影响,差异自然消失。g1是单指令立即数移动、g3是xor + lea组合,lea的可用端口固定为p1/p5,不受解码阶段调度偏向影响,所以32位和64位版本的端口分布没有差异,只有g2的双ALU通用指令组合会出现该现象。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:54:01