Mar*_*oom 9 x86 assembly cpu-architecture intel-pmu
我正在使用一个非常简单的循环开始调查我的Haswell端口0上的分支单元的功能:
BITS 64
GLOBAL _start
SECTION .text
_start:
mov ecx, 10000000
.loop:
dec ecx ;|
jz .end ;| 1 uOP (call it D)
jmp .loop ;| 1 uOP (call it J)
.end:
mov eax, 60
xor edi, edi
syscall
Run Code Online (Sandbox Code Playgroud)
使用perf我们看到循环以1c/iter运行
Performance counter stats for './main' (50 runs):
10,001,055 uops_executed_port_port_6 ( +- 0.00% )
9,999,973 uops_executed_port_port_0 ( +- 0.00% )
10,015,414 cycles:u ( +- 0.02% )
23 resource_stalls_rs ( +- 64.05% )
Run Code Online (Sandbox Code Playgroud)
我对这些结果的解释是:
但是,我们也可以看到RS永远不会满员.
它最多可以以2 uOPs/c的速率发送uOP,但理论上可以得到4 uOPs/c,导致大约30 c的完整RS(对于具有60个融合域条目的RS).
根据我的理解,应该有很少的分支误预测,而且uOP都应该来自LSD.
所以我看了FE:
8,239,091 lsd_cycles_active ( +- 3.10% )
989,320 idq_dsb_cycles ( +- 23.47% )
2,534,972 idq_mite_cycles ( +- 15.43% )
4,929 idq_ms_uops ( +- 8.30% )
0.007429733 seconds time elapsed ( +- 1.79% )
Run Code Online (Sandbox Code Playgroud)
确认FE从LSD 1发出.
但是,LSD永远不会发出4个uOPs/c:
7,591,866 lsd_cycles_active ( +- 3.17% )
0 lsd_cycles_4_uops
Run Code Online (Sandbox Code Playgroud)
我的解释是LSD不能从下一次迭代2发出uOP,因此每个周期只发送DJ对到BE.
我的解释是否正确?
源代码在此存储库中.
1存在一些差异,我认为这是由于允许某些上下文切换的大量迭代.
2在具有有限电路深度的硬件中,这听起来相当复杂.
循环中的所有微指令都是分支(每次迭代2个)。我认为`lsd_cycles_4_uops为零的原因是由于重命名器中的限制。根据《英特尔优化手册》第2.4.3.1节:
与之前的微体系结构中的每个分支一个分支相比,重命名器每个周期可以分配两个分支。这样可以消除执行过程中的气泡。
这是有关桑迪桥微体系结构的一部分的小节。但是据我所知,这适用于所有以后的微体系结构。每个周期最大重命名吞吐量为4微秒。但是最多两个对象可以是分支。因此,在所有微指令都是分支的示例中,即使在循环的第一次迭代中,LSD在任何给定的周期也永远不会传递超过2微指令。
因此,将在每个周期中在RS中分配2个分支uo,并且每个周期都可以调度这两个分支。因此,RS占用率不会增加。
此限制不会影响程序的性能。每个周期执行2个分支指令,每个周期提供3个IPC已经是最佳选择。
我试图找到一个性能事件,由于该限制,该事件可以捕获分配器停顿。在这种情况下,事件RESOURCE_STALLS.ANY和UOPS_ISSUED.ANY(以及cmask= 1和inv= 1)似乎无关紧要。@IwillnotexistIdonotexist建议使用
IDQ_UOPS_NOT_DELIVERED.CORE。我在下面介绍了性能事件及其所有受支持的变体的结果。我也提供了这些事件的正确含义,因为该手册是错误的。T表示迭代次数。
IDQ_UOPS_NOT_DELIVERED.CORE:计算分配器未使用的插槽数。如果程序运行了C个核心周期,则插槽总数为4 * C。测量值几乎等于2 * T。由于周期数为T,因此时隙数为4 * T,这意味着大约没有使用发行时隙的一半。
IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE:计算从IDQ传递零微分的周期数。测量值可以忽略不计。
IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_1_UOP_DELIV.CORE:计算从IDQ传送最多1微秒的周期数。测量值可以忽略不计。
IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_2_UOP_DELIV.CORE:计算从IDQ传送最多2微秒的周期数:测量值几乎等于T。
IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_3_UOP_DELIV.CORE:计算从IDQ最多发送3微秒的周期数:测量值几乎等于T。
因此,由于执行时间几乎等于T个核心周期,因此可以得出结论,分配器在大多数周期中每个周期只分配正好2 oups,这等于分配率。
请注意,Haswell和Skylake中的RS包含未融合的uops。因此,每个条目都可以容纳一个未融合的uop。参见脚注2。但这无关紧要,因为没有微融合。
| 归档时间: |
|
| 查看次数: |
286 次 |
| 最近记录: |