当前位置: 首页 > 知识库问答 >
问题:

最近英特尔微架构中的简单解码器能否处理所有1-μop指令?

马高谊
2023-03-14

共有1个答案

景子安
2023-03-14

Andreas的注释表明XOR eax,eax/Setnle al似乎有1/时钟的解码瓶颈。我在cdq中发现了同样的事情:读EAX、写EDX,从DSB(uop缓存)中运行的速度也明显更快,并且不涉及部分寄存器或任何奇怪的事情,也不需要DEP中断指令。

更好的是,作为一个单字节指令,它只需要很短的指令块就可以击败DSB。(导致在某些CPU上测试的错误结果,例如Agner Fog的表和https://uops.info/上,例如SKX显示为1C吞吐量。)https://www.uops.info/html-tp/skx/cdq-measurements.html与https://www.uops.info/html-tp/cfl/cdq-measurements.html的吞吐量不一致,因为测试方法不同:只有Coffee Lake测试使用足够小的展开计数(10)来测试DSB,发现吞吐量为0.6。(如果考虑到循环开销,实际吞吐量是0.5,完全由后端端口压力解释,与cqo.IDK相同,为什么在循环中p6只有一个额外的uop时,您会发现0.6而不是0.55。)

(Zen可以以0.25C的吞吐量运行这些指令;没有奇怪的解码问题,并且可以由每个整数ALU端口处理。)

dec/jnz循环中的乘以10 cdq可以从uop缓存中运行,并且在Skylake上以0.5C吞吐量运行(p06),外加循环开销,该开销也会争夺P6。

对于一个32字节的机器代码块,乘以20 cdq大于3个uop缓存行,这意味着循环只能从传统解码运行(循环顶部对齐)。在Skylake上,每个CDQ运行1个周期。Perf计数器确认MITE每个循环交付1个uop,而不是3个或4个中间有空闲循环的组。

default rel
%ifdef __YASM_VER__
    CPU Skylake AMD
%else
%use smartalign
alignmode p6, 64
%endif

global _start
_start:
    mov  ebp, 1000000000

align 64
.loop:
    ;times 10 cdq   ; 0.5c throughput
    ;times 20 cdq   ; 1c throughput, 1 MITE uop per cycle front-end

    ; times 10 cqo        ; 0.5c throughput 2-byte insn fits uop cache
    ; times 10 cdqe       ; 1c throughput data dependency
    ;times 10 cld         ; ~4c throughput, 3 uops

    dec ebp
    jnz .loop
.end:

    xor edi,edi
    mov eax,231   ; __NR_exit_group  from /usr/include/asm/unistd_64.h
    syscall       ; sys_exit_group(0)

在我的Arch Linux桌面上,我将其构建到一个静态可执行文件中,以在perf下运行:

    null
     in a bash shell:
t=cdq-latency; nasm -f elf64 "$t".asm && ld -o "$t" "$t.o" && objdump -drwC -Mintel "$t" && taskset -c 3 perf stat --all-user -etask-clock,context-switches,cpu-migrations,page-faults,cycles,instructions,uops_issued.any,frontend_retired.dsb_miss,idq.dsb_uops,idq.mite_uops,idq.mite_cycles,idq_uops_not_delivered.core,idq_uops_not_delivered.cycles_fe_was_ok,idq.all_mite_cycles_4_uops ./"$t"
0000000000401000 <_start>:
  401000:       bd 00 ca 9a 3b          mov    ebp,0x3b9aca00
  401005:       0f 1f 84 00 00 00 00 00         nop    DWORD PTR [rax+rax*1+0x0]
...
  40103d:       0f 1f 00                nop    DWORD PTR [rax]

0000000000401040 <_start.loop>:
  401040:       99                      cdq    
  401041:       99                      cdq    
  401042:       99                      cdq    
  401043:       99                      cdq    
...
  401052:       99                      cdq    
  401053:       99                      cdq             # 20 total CDQ
  401054:       ff cd                   dec    ebp
  401056:       75 e8                   jne    401040 <_start.loop>

0000000000401058 <_start.end>:
  401058:       31 ff                   xor    edi,edi
  40105a:       b8 e7 00 00 00          mov    eax,0xe7
  40105f:       0f 05                   syscall 

Perf结果:

 Performance counter stats for './cdq-latency':

          5,205.44 msec task-clock                #    1.000 CPUs utilized          
                 0      context-switches          #    0.000 K/sec                  
                 0      cpu-migrations            #    0.000 K/sec                  
                 1      page-faults               #    0.000 K/sec                  
    20,124,711,776      cycles                    #    3.866 GHz                      (49.88%)
    22,015,118,295      instructions              #    1.09  insn per cycle           (59.91%)
    21,004,212,389      uops_issued.any           # 4035.049 M/sec                    (59.97%)
     1,005,872,141      frontend_retired.dsb_miss #  193.235 M/sec                    (60.03%)
                 0      idq.dsb_uops              #    0.000 K/sec                    (60.08%)
    20,997,157,414      idq.mite_uops             # 4033.694 M/sec                    (60.12%)
    19,996,447,738      idq.mite_cycles           # 3841.451 M/sec                    (40.03%)
    59,048,559,790      idq_uops_not_delivered.core # 11343.621 M/sec                   (39.97%)
       112,956,733      idq_uops_not_delivered.cycles_fe_was_ok #   21.700 M/sec                    (39.92%)
           209,490      idq.all_mite_cycles_4_uops #    0.040 M/sec                    (39.88%)

       5.206491348 seconds time elapsed

因此,循环开销(dec/jnz)基本上是免费的,解码的周期与上一次CDQ相同。计数并不准确,因为我在一次运行中使用了太多事件(启用了HT),所以perf进行了软件复用。从另一个计数器较少的运行:

# same source, only these HW counters enabled to avoid multiplexing
          5,161.14 msec task-clock                #    1.000 CPUs utilized          

    20,107,065,550      cycles                    #    3.896 GHz                    
    20,000,134,955      idq.mite_cycles           # 3875.142 M/sec                  
    59,050,860,720      idq_uops_not_delivered.core # 11441.447 M/sec                 
        95,968,317      idq_uops_not_delivered.cycles_fe_was_ok #   18.594 M/sec                  

所以我们可以看到,MITE(legacy decode)基本上每个周期都是活跃的,前端基本上从来没有“OK”。(即从不在后端停顿)。

...
0000000000401040 <_start.loop>:
  401040:       99                      cdq    
  401041:       99                      cdq    
...
  401049:       99                      cdq        # 10 total CDQ insns
  40104a:       ff cd                   dec    ebp
  40104c:       75 f2                   jne    401040 <_start.loop>

 Performance counter stats for './cdq-latency' (4 runs):

          1,417.38 msec task-clock                #    1.000 CPUs utilized            ( +-  0.03% )
                 0      context-switches          #    0.000 K/sec                  
                 0      cpu-migrations            #    0.000 K/sec                  
                 1      page-faults               #    0.001 K/sec                  
     5,511,283,047      cycles                    #    3.888 GHz                      ( +-  0.03% )  (49.83%)
    11,997,247,694      instructions              #    2.18  insn per cycle           ( +-  0.00% )  (59.99%)
    10,999,182,841      uops_issued.any           # 7760.224 M/sec                    ( +-  0.00% )  (60.17%)
           197,753      frontend_retired.dsb_miss #    0.140 M/sec                    ( +- 13.62% )  (60.21%)
    10,988,958,908      idq.dsb_uops              # 7753.010 M/sec                    ( +-  0.03% )  (60.21%)
        10,234,859      idq.mite_uops             #    7.221 M/sec                    ( +- 27.43% )  (60.21%)
         8,114,909      idq.mite_cycles           #    5.725 M/sec                    ( +- 26.11% )  (39.83%)
        40,588,332      idq_uops_not_delivered.core #   28.636 M/sec                    ( +- 21.83% )  (39.79%)
     5,502,581,002      idq_uops_not_delivered.cycles_fe_was_ok # 3882.221 M/sec                    ( +-  0.01% )  (39.79%)
            56,223      idq.all_mite_cycles_4_uops #    0.040 M/sec                    ( +-  3.32% )  (39.79%)

          1.417599 +- 0.000489 seconds time elapsed  ( +-  0.03% )
 类似资料:
  • 问题内容: 从我读到的内容来看,它用于修复CPU中的错误,而无需修改BIOS。根据我对汇编的基本知识,我知道汇编指令在内部由CPU分解为微代码,并相应地执行。但是intel以某种方式可以在系统启动和运行时进行一些更新。 有人有更多信息吗?是否有关于微码可以做什么以及如何使用的文档? 编辑:我读过维基百科的文章:没弄清楚我怎么能自己写一些,以及它有什么用。 问题答案: 在较早的时期,微代码在CPU中

  • 在Barry B. Brey的《智能微处理器》一书中写道 在64位模式下不允许,但在32位或16位模式下允许。如果可以在64位模式下允许MOV AL,1,那么MOV AH,1有什么问题?

  • 第3.5.1节下的英特尔优化参考建议: “支持单个微操作指令。” "避免使用具有超过4个微操作并且需要多个周期来解码的复杂指令(例如,回车、离开或循环)。改用简单指令序列。" 虽然英特尔自己告诉编译器编写者使用解码为几个微操作的指令,但我在他们的任何手册中都找不到任何解释每个ASM指令解码为多少微操作的说明!这些信息在任何地方都可以找到吗?(当然,我预计不同代CPU的答案会有所不同。)

  • 我有一个带有四个麦克风卡(mic0-mic3)的服务器,它工作得很好。我想禁用一些麦克风,例如mic3,现在只有mic0-mic2可用。我该怎么办?

  • 在《英特尔内部指令指南》中指出,名为“sqrtsd”的指令的延迟为18个周期。 我用自己的程序测试了它,例如,如果我们将0.15作为输入,它是正确的。但是当我们取256(或任何2^x)数字时,延迟只有13。为什么? 我的一个理论是,由于13是“sqrtss”的延迟,这与“sqrtsd”相同,但在32位浮点上完成,那么处理器可能足够聪明,能够理解256可以容纳在32位中,因此使用该版本,而0.15需

  • 给定一个大小为N×m的二进制矩阵,任务是为每个单元寻找矩阵中最近的1的距离。该距离计算为I1-I2+J1-J2,其中i1、j1是当前单元的行号和列号,i2、j2是最近单元的行号和列号,其值为1。 输入:输入的第一行是表示测试用例数量的整数T。然后T测试用例就会接踵而至。每个测试用例由2行组成。每个测试用例的第一行包含两个表示矩阵行数和列数的整数M和N。然后在下一行中是矩阵(mat)的n*m个空格分