Whiskey Lake i7-8565U/Ubuntu 18.04/HT enabled
考虑以下代码,该代码将寄存器 ymm0ymm1 中的一些垃圾数据写入 16 MiB 静态分配的 WB 内存,循环由 6400 次迭代组成(因此页面错误影响可以忽略不计):

;rdx = 16MiB >> 3
xor rcx, rcx
store_loop:
vmovdqa [rdi + rcx*8], ymm0
vmovdqa [rdi + rcx*8 + 0x20], ymm1
add rcx, 0x08
cmp rdx, rcx
ja store_loop

使用 taskset -c 3 ./bin 我正在通过此示例测量 RFO 请求,结果如下:
Performance counter stats for 'taskset -c 3 ./bin':

     1 695 029 000      L1-dcache-load-misses     # 2325,60% of all L1-dcache hits    (24,93%)
        72 885 527      L1-dcache-loads                                               (24,99%)
     3 411 237 144      L1-dcache-stores                                              (25,05%)
       946 374 671      l2_rqsts.all_rfo                                              (25,11%)
       451 047 123      l2_rqsts.rfo_hit                                              (25,15%)
       495 868 337      l2_rqsts.rfo_miss                                             (25,15%)
     2 367 931 179      l2_rqsts.all_pf                                               (25,14%)
       568 168 558      l2_rqsts.pf_hit                                               (25,08%)
     1 785 300 075      l2_rqsts.pf_miss                                              (25,02%)
     1 217 663 928      offcore_requests.demand_rfo                                     (24,96%)
     1 963 262 031      offcore_response.demand_rfo.any_response                                     (24,91%)
           108 536      dTLB-load-misses          #    0,20% of all dTLB cache hits   (24,91%)
        55 540 014      dTLB-loads                                                    (24,91%)
        26 310 618      dTLB-store-misses                                             (24,91%)
     3 412 849 640      dTLB-stores                                                   (24,91%)
    27 265 942 916      cycles                                                        (24,91%)

       6,681218065 seconds time elapsed

       6,584426000 seconds user
       0,096006000 seconds sys
l2_rqsts.all_rfo 的描述是



建议 DCU 可以执行某种 RFO 预取。从 Intel Optimization Manual/2.6.2.4 对 DCU 的描述中不清楚:



所以我猜 DCU 遵循“访问类型”:如果它是 RFO,那么 DCU 会执行 RFO 预取。

所有这些 RFO 预取都应该与需求 RFO 一起进入 L2,并且只有其中一些( l2_rqsts.rfo_miss )应该进入非核心。 offcore_requests.demand_rfo 只计算需求 rfo,但 l2_rqsts.rfo_miss 计算所有 rfo(需求 + dcu prefectch),这意味着不等式 offcore_requests.demand_rfo < l2_rqsts.rfo_miss 应该成立。

问题 1: 为什么 l2_rqsts.rfo_missoffcore_requests.demand_rfo 少很多(甚至 l2_rqsts.all_rfooffcore_requests.demand_rfo 少)

我预计需求 offcore_requests.demand_rfo 可以与 offcore_response.demand_rfo.any_response 匹配,因此这些 Core PMU 事件的数量应该大致相等

问题 2: 为什么 offcore_response.demand_rfo.any_response 几乎是 offcore_requests.demand_rfo 的 1.5 倍?

我猜 L2-streamer 也会做一些 RFO 预取,但无论如何都不应该在 offcore_requests.demand_rfo 中考虑。

UPD :
$ sudo rdmsr -p 3 0x1A4
1

L2-Streamer 关闭
 Performance counter stats for 'taskset -c 3 ./bin':

     1 672 633 985      L1-dcache-load-misses     # 2272,75% of all L1-dcache hits    (24,96%)
        73 595 056      L1-dcache-loads                                               (25,00%)
     3 409 928 481      L1-dcache-stores                                              (25,00%)
     1 593 190 436      l2_rqsts.all_rfo                                              (25,04%)
        16 582 758      l2_rqsts.rfo_hit                                              (25,07%)
     1 579 107 608      l2_rqsts.rfo_miss                                             (25,07%)
       124 294 129      l2_rqsts.all_pf                                               (25,07%)
        22 674 837      l2_rqsts.pf_hit                                               (25,07%)
       102 019 160      l2_rqsts.pf_miss                                              (25,07%)
     1 661 232 864      offcore_requests.demand_rfo                                     (25,02%)
     3 287 688 173      offcore_response.demand_rfo.any_response                                     (24,98%)
           139 247      dTLB-load-misses          #    0,25% of all dTLB cache hits   (24,94%)
        56 823 458      dTLB-loads                                                    (24,90%)
        26 343 286      dTLB-store-misses                                             (24,90%)
     3 384 264 241      dTLB-stores                                                   (24,94%)
    37 782 766 410      cycles                                                        (24,94%)

       9,320791474 seconds time elapsed

       9,213383000 seconds user
       0,099928000 seconds sys

可以看出 offcore_requests.demand_rfo 更接近 l2_rqsts.rfo_miss ,但仍然存在一些差异。在 OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD 的英特尔文档中,我发现了以下内容:



所以我的猜测是 L2 预取被提升为 Demand 并计入 Demand offcore 请求。但它并没有解释 offcore_response.demand_rfo.any_responseoffcore_requests.demand_rfo 之间的区别,现在几乎是两倍:
offcore_requests.demand_rfo 1 661 232 864
对比
offcore_response.demand_rfo.any_response 3 287 688 173
UPD:
$ sudo rdmsr -p 3 0x1A4
3

所有 L2 预取器关闭
 Performance counter stats for 'taskset -c 3 ./bin':

     1 686 560 752      L1-dcache-load-misses     # 2138,14% of all L1-dcache hits    (23,44%)
        78 879 830      L1-dcache-loads                                               (23,48%)
     3 409 552 015      L1-dcache-stores                                              (23,53%)
     1 670 187 931      l2_rqsts.all_rfo                                              (23,56%)
            15 674      l2_rqsts.rfo_hit                                              (23,59%)
     1 676 538 346      l2_rqsts.rfo_miss                                             (23,58%)
           156 206      l2_rqsts.all_pf                                               (23,59%)
            14 436      l2_rqsts.pf_hit                                               (23,59%)
           173 163      l2_rqsts.pf_miss                                              (23,59%)
     1 671 606 174      offcore_requests.demand_rfo                                     (23,59%)
     3 301 546 970      offcore_response.demand_rfo.any_response                                     (23,59%)
           140 335      dTLB-load-misses          #    0,21% of all dTLB cache hits   (23,57%)
        68 010 546      dTLB-loads                                                    (23,53%)
        26 329 766      dTLB-store-misses                                             (23,49%)
     3 429 416 286      dTLB-stores                                                   (23,45%)
    39 462 328 435      cycles                                                        (23,42%)

       9,699770319 seconds time elapsed

       9,596304000 seconds user
       0,099961000 seconds sys

现在到 l2 的预取请求总数(来自所有预取器)是 156 206 l2_rqsts.all_pf

UPD:
$ sudo rdmsr -p 3 0x1A4
7

̶A̶l̶l̶ ̶p̶r̶e̶f̶e̶t̶c̶h̶e̶r̶s̶ ̶t̶u̶r̶n̶e̶d̶ ̶o̶f̶f̶.̶ 仅启用IP预取器
 Performance counter stats for 'taskset -c 3 ./bin':

     1 672 643 256      L1-dcache-load-misses     # 1893,36% of all L1-dcache hits    (24,92%)
        88 342 382      L1-dcache-loads                                               (24,96%)
     3 411 575 868      L1-dcache-stores                                              (25,00%)
     1 672 628 218      l2_rqsts.all_rfo                                              (25,04%)
            10 585      l2_rqsts.rfo_hit                                              (25,04%)
     1 684 510 576      l2_rqsts.rfo_miss                                             (25,04%)
            10 042      l2_rqsts.all_pf                                               (25,04%)
             4 368      l2_rqsts.pf_hit                                               (25,05%)
             9 135      l2_rqsts.pf_miss                                              (25,05%)
     1 684 136 160      offcore_requests.demand_rfo                                     (25,05%)
     3 316 673 543      offcore_response.demand_rfo.any_response                                     (25,05%)
           133 322      dTLB-load-misses          #    0,21% of all dTLB cache hits   (25,03%)
        64 283 883      dTLB-loads                                                    (24,99%)
        26 195 527      dTLB-store-misses                                             (24,95%)
     3 392 779 428      dTLB-stores                                                   (24,91%)
    39 627 346 050      cycles                                                        (24,88%)

       9,710779347 seconds time elapsed

       9,610209000 seconds user
       0,099981000 seconds sys

UPD:
$ sudo rdmsr -p 3 0x1A4
f

禁用所有预取器
 Performance counter stats for 'taskset -c 3 ./bin':

     1 695 710 457      L1-dcache-load-misses     # 2052,21% of all L1-dcache hits    (23,47%)
        82 628 503      L1-dcache-loads                                               (23,47%)
     3 429 579 614      L1-dcache-stores                                              (23,47%)
     1 682 110 906      l2_rqsts.all_rfo                                              (23,51%)
            12 315      l2_rqsts.rfo_hit                                              (23,55%)
     1 672 591 830      l2_rqsts.rfo_miss                                             (23,55%)
                 0      l2_rqsts.all_pf                                               (23,55%)
                 0      l2_rqsts.pf_hit                                               (23,55%)
                12      l2_rqsts.pf_miss                                              (23,55%)
     1 662 163 396      offcore_requests.demand_rfo                                     (23,55%)
     3 282 743 626      offcore_response.demand_rfo.any_response                                     (23,55%)
           126 739      dTLB-load-misses          #    0,21% of all dTLB cache hits   (23,55%)
        59 790 090      dTLB-loads                                                    (23,55%)
        26 373 257      dTLB-store-misses                                             (23,55%)
     3 426 860 516      dTLB-stores                                                   (23,55%)
    38 282 401 051      cycles                                                        (23,51%)

       9,377335173 seconds time elapsed

       9,281050000 seconds user
       0,096010000 seconds sys

即使预取器被禁用,perf 仍将 12 报告为 pf_miss(可在不同的运行中以不同的值重现)。这可能是计数错误。此外,1 672 591 830 l2_rqsts.rfo_miss 的值略大于 1 662 163 396 offcore_requests.demand_rfo,我也倾向于将其解释为计数错误。

假设: DCU RFO 预取丢失 L2 和离开核心在 offcore_requests.demand_rfo 中。

如果 L2-streamer 关闭,该假设有效: 102 019 160 l2_rqsts.pf_miss + 1 579 107 608 l2_rqsts.rfo_miss = 1 681 126 7681 661 232 864 offcore_requests.demand_rfo
如果所有预取器都关闭,该假设也适用: 1 684 510 576 l2_rqsts.rfo_miss ; 1 684 136 160 offcore_requests

在所有 PF 关闭的情况下,L1-dcache-load-misses 大约等于 l2_rqsts.rfo_miss,而 offcore_requests.demand_rfo 又等于 offcore_response.demand_rfo.any_response
我仍然不知道为什么 offcore_requests.demand_rfo 的值比 ojit_code 大得多

最佳答案

在我看来,循环正在写入 2^18 个缓存行,并且有一个外循环(问题中未显示)执行内循环(所示的那个)6400 次。因此,预期的需求 RFO 总数为 2^18*6400 = 1,677,721,600 条,预期停用的商店指令数为 1677721600*2 = 3,355,443,200。实测L1-dcache-stores门店数量约为34.10亿,比预期增加了约5500万。这个事件计数应该是准确的,所以我认为问题中没有显示影响事件计数的其他代码。加载事件计数还表明有许多加载来自某处,这对事件 l2_rqsts.all_pfl2_rqsts.pf_hitl2_rqsts.pf_miss 的计数有重大影响。我已经问过我的评论中是否有任何其他重要的代码包含在测量中。

从启用所有预取器的第一个实验的结果来看,l2_rqsts.rfo_hit + offcore_requests.demand_rfo 加起来的数量几乎等于需求 RFO 的预期数量。 L2 流传输器实际上可以预取 RFO,如英特尔优化手册中所述,该手册解释了如何存在 l2_rqsts.rfo_hit 。我不知道为什么 l2_rqsts.rfo_miss 不等于 offcore_requests.demand_rfo 。我认为事件 offcore_requests.demand_rfo 是准确的。尝试仅禁用 L1D 预取器并保持启用 L2 预取器,然后查看执行时间是否增加。如果 L1D 预取器实际上发送了大量的 RFO,则 L1D 中应该有足够的写入命中,从而对性能产生影响。

禁用 L2 流光的第二个实验的结果非常接近预期。 l2_rqsts.rfo_hit 非常小并且 l2_rqsts.all_rfo 几乎等于 offcore_requests.demand_rfo ,这等于需求 RFO 的预期数量。这提供了 L1D 预取器不预取 RFO 的实验证据。在这种情况下,l2_rqsts.all_pf 应该为零,因为两个 L2 预取器都被禁用。

在上一个实验中,您只关闭了四个数据缓存预取器中的三个;你错过了 DCU IP 预取器。在这种情况下,2_rqsts.all_rfo 的计数甚至更接近于异常(exception)情况。尝试禁用 DCU IP 预取器并查看 l2_rqsts.rfo_hit (可能还有 l2_rqsts.all_pf )是否为零。

您的处理器的规范更新文档中的 Erratum 058offcore_response.demand_rfo.any_response 可能会过度计算,可以使用 offcore_requests.demand_rfo 代替。这解释了为什么 offcore_response.demand_rfo.any_response 大于所有实验中的预期值,并且还表明 offcore_requests.demand_rfo 是可靠的。

关于assembly - 为什么对非核心响应/非核心请求的需求过多?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60390539/

10-11 18:36