当前位置 : 主页 > 网络安全 > 测试自动化 >

性能 – 哪个Intel微体系结构引入了ADC reg,0单Uop特殊情况?

来源:互联网 收集:自由互联 发布时间:2021-06-22
Haswell及更早版本的ADC通常为2 uops,具有2个周期延迟,因为Intel uops传统上只能有2个输入( https://agner.org/optimize/). Broadwell / Skylake后来有单uop ADC / SBB / CMOV,在Haswell为FMA引入了3输入uop,在某些情
Haswell及更早版本的ADC通常为2 uops,具有2个周期延迟,因为Intel uops传统上只能有2个输入( https://agner.org/optimize/). Broadwell / Skylake后来有单uop ADC / SBB / CMOV,在Haswell为FMA引入了3输入uop,在某些情况下引入了 micro-fusion of indexed addressing modes.

(但不是adc al,imm8短格式编码,或其他al / ax / eax / rax,imm8 / 16/32/32短格式,没有ModRM.我的答案中有更多细节.)

但是,即时0的adc特别适用于Haswell解码为只有一个uop. @BeeOnRope tested this,包括performance quirk在他的uarch-bench中的检查:https://github.com/travisdowns/uarch-bench.CI on a Haswell server的样本输出显示adc reg,0和adc reg,1或adc reg,zeroed-reg之间的差异.

(对于SBB也是如此.就我所见,在任何CPU上具有相同立即数的等效编码,ADC和SBB性能之间从来没有任何差别.)

这个针对imm = 0的优化是什么时候引入的?

我在Core 21上测试过,发现adc eax,0延迟是2个周期,与adc eax相同,3.并且,对于0和3的吞吐量测试的一些变化,循环计数是相同的,因此第一代Core 2(Conroe / Merom)不进行此优化.

回答这个问题的最简单方法可能是在Sandybridge系统上使用我的测试程序,看看adc eax,0是否比adc eax快1.但基于可靠文档的答案也可以.

(顺便说一句,如果有人可以访问Sandybridge上的perf计数器,你也可以通过运行@ BeeOnRope的测试代码来清除Is performance reduced when executing loops whose uop count is not a multiple of processor width?的神秘面纱.或者我在不再使用的SnB上观察到的性能急剧下降只是因为un – 层压与普通的uops不同?)

脚注1:我在运行Linux的Core 2 E6600(Conroe / Merom)上使用了这个测试程序.

;; NASM / YASM
;; assemble / link this into a 32 or 64-bit static executable.

global _start
_start:
mov     ebp, 100000000

align 32
.loop:

    xor  ebx,ebx  ; avoid partial-flag stall but don't break the eax dependency
%rep 5
    adc    eax, 0   ; should decode in a 2+1+1+1 pattern
    add    eax, 0
    add    eax, 0
    add    eax, 0
%endrep

    dec ebp       ; I could have just used SUB here to avoid a partial-flag stall
    jg .loop


%ifidn __OUTPUT_FORMAT__, elf32
   ;; 32-bit sys_exit would work in 64-bit executables on most systems, but not all.  Some, notably Window's subsystem for Linux, disable IA32 compat
    mov eax,1
    xor ebx,ebx
    int 0x80     ; sys_exit(0) 32-bit ABI
%else
    xor edi,edi
    mov eax,231   ; __NR_exit_group  from /usr/include/asm/unistd_64.h
    syscall       ; sys_exit_group(0)
%endif

Linux perf在像Core 2这样的旧CPU上运行得不好(它不知道如何访问像uops这样的所有事件),但它确实知道如何读取硬件计数器的周期和指令.这就足够了.

我用它构建和描述了这个

yasm -felf64 -gdwarf2 testloop.asm
 ld -o testloop-adc+3xadd-eax,imm=0 testloop.o

    # optional: taskset pins it to core 1 to avoid CPU migrations
 taskset -c 1 perf stat -e task-clock,context-switches,cycles,instructions ./testloop-adc+3xadd-eax,imm=0

 Performance counter stats for './testloop-adc+3xadd-eax,imm=0':

       1061.697759      task-clock (msec)         #    0.992 CPUs utilized          
               100      context-switches          #    0.094 K/sec                  
     2,545,252,377      cycles                    #    2.397 GHz                    
     2,301,845,298      instructions              #    0.90  insns per cycle        

       1.069743469 seconds time elapsed

0.9 IPC是一个有趣的数字.

这与我们期望的静态分析有2 uop / 2c延迟adc:(5 *(1 3)3)= 23个循环中的指令,5 *(2 3)= 25个周期的延迟=每个周期循环迭代. 23/25 = 0.92.

Skylake的赔率为1.15. (5 *(1 3)3)/(5 *(1 3))= 1.15,即额外.15来自xor-zero和dec / jg,而adc / add链每个时钟正好以1 uop运行,延迟瓶颈.我们期望这个1.15整体IPC在任何其他uarch上也具有单周期延迟adc,因为前端不是瓶颈. (有序Atom和P5 Pentium会略低,但xor和dec可以与adc配对或在P5上添加.)

在SKL上,uops_issued.any = instructions = 2.303G,确认adc是单个uop(它始终在SKL上,无论立即有什么值).偶然地,jg是新缓存行中的第一条指令,因此它不会与SKL上的dec进行宏观融合.使用dec rbp或sub ebp,而不是uops_issued.any是预期的2.2G.

这是非常可重复的:perf stat -r5(运行5次并显示平均方差),以及多次运行,显示循环计数可重复到1000分中的1分.1c与adc中的2c延迟会产生很大的影响比那更大的差异.

使用0以外的立即数重建可执行文件并不会改变Core 2上的时间,这是另一个没有特殊情况的强烈信号.这绝对值得测试.

我最初看的是吞吐量(在每次循环迭代之前使用xor eax,eax,让OoO exec重叠迭代),但很难排除前端效果.我想我最终通过添加单uop添加指令避免了前端瓶颈.内循环的吞吐量测试版本如下所示:

xor  eax,eax  ; break the eax and CF dependency
%rep 5
    adc    eax, 0   ; should decode in a 2+1+1+1 pattern
    add    ebx, 0
    add    ecx, 0
    add    edx, 0
%endrep

这就是延迟测试版看起来有点奇怪的原因.但无论如何,请记住Core2没有解码的uop缓存,并且其循环缓冲区处于预解码阶段(在找到指令边界之后). 4个解码器中只有1个可以解码多uop指令,因此adc在前端是多uop瓶颈.我想我可以让这种情况发生,时间5 adc eax,0,因为管道的某个后期阶段不可能在不执行它的情况下抛出该uop.

Nehalem的循环缓冲区可以回收已解码的uop,并且可以避免解码背对背多uop指令的瓶颈问题.

根据我的微基准测试,其结果可以在 uops.info找到,这个优化是在Sandy Bridge( http://www.uops.info/html-tp/SNB/ADC-2055-Measurements.html)中引入的. Westmere没有做这个优化( http://www.uops.info/html-tp/WSM/ADC-2055-Measurements.html).使用Core i7-2600和Core i5-650获得数据.

此外,uops.info上的数据表明,如果使用8位寄存器,则不执行优化(Sandy Bridge,Ivy Bridge,Haswell).

网友评论