本文介绍了32位和64位寄存器会导致CPU微体系结构的差异吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将Peter Cordes在his answer中提到的方法与‘将CPU寄存器中的所有位设置为1’的问题进行比较。

因此,我编写了一个基准测试,将所有13个寄存器设置为除e/rspe/rbpe/rcx之外的所有位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

我测试了他提到的以下方法,Full code in here

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

第1组a移动传真,-1测试7
组1 bmov rax,-1测试3
组2 a异或eax、eax/dec eax测试6
组2 bxor eax,eax/dec rax测试2
组3 a异或ECX、ECX/Lea eax、[RCX-1]测试0
组3 bXOR ECX、ECX/Lea Rax、[RCX-1]test-1(测试00)
组4 a或eax,-1测试5
组4 b或RAX,-1测试1

下表显示,从组1到组3,使用64位寄存器时,每个循环多1个周期。

IDQ_UOPS_NOT_DELIVERED也增加了,这可能解释了周期数增加的原因。但这能否解释每个循环多1个周期的确切原因?

g1a1300,903,7051,300,104,496800,055,137601,487,115
g1b1,400,852,9311,400,092,325800,049,3131,001,524,712
g2a1600,920,1561,600,113,4801300,061,359501,522,554
G2B1700,834,7691700,108,6881300,057,576901,467,008
g3a1,701,971,4251700,093,2981300,111,482902,327,493
g3b1,800,891,8611800,110,0961300,059,3381,301,497,001
g4a1,201,164,2081,200,122,2751100,049,081201,592,292
g4b1,200,553,5771200,074,4221100,031,729200,772,985

此外,g2a和g2b的端口分布不同,不同于g1a和g1b(g1a和g1b端口分布相同),也不同于g3a和g3b。

如果我评论times 32 nop,这种现象就会消失。与尘螨有关吗?

g1a299,868,019300,014,6575925779416,589300,279,232499,885,2947,242
g1b299,935,968300,085,0896622875818,842299,935,445500,426,4367,336
g2a299,800,192299,758,4607,4619,63520,622399,836,486400,312,3548,446
G2B200,047,079200,203,0267899996721,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,5355383670515,344400,045,302500,364,3776,802
g4b200,224,703300,284,60954647,03115,817400,047,050499,467,5466746

环境:英特尔i7-10700、ubuntu20.04和NASM 2.14.02。

对我来说,用英语解释这个有点难。如果描述不清楚,请注明。

推荐答案

您所有示例中的瓶颈是预解码器。

我用我的模拟器uiCA(https://uica.uops.info/https://github.com/andreas-abel/uiCA)分析了您的示例。它预测以下吞吐量,与您的测量结果非常接近:

uiCA生成的跟踪表提供了有关代码如何执行的一些信息。例如,对于g1a,它生成以下跟踪:

您可以看到,对于32个NOP,预解码器需要8个周期,而对于其余指令,它需要5个周期,这些周期加在一起相当于您测量的13个周期。

您可能会注意到,在某些周期中,只对少量指令进行预解码;例如,在第四个周期中,只对一条指令进行预解码。这是因为预解码器在对齐的16字节块上工作,并且它每个周期最多可以处理5条指令(请注意,一些来源错误地声称它每个周期可以处理6条指令)。您可以在this paper中找到有关预解码器的更多详细信息,例如它如何处理跨越16字节边界的指令。

如果将此跟踪与g1b的跟踪进行比较,您可以看到,NOPS之后的指令现在需要6个周期而不是5个周期来预解码,这是因为G1b中的几个指令比G1a中的相应指令更长。

这篇关于32位和64位寄存器会导致CPU微体系结构的差异吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 07:56