Почему слишком много запросов / ответов вне форума? - PullRequest
3 голосов
/ 25 февраля 2020

Whiskey Lake i7-8565U / Ubuntu 18.04 / HT enabled

Рассмотрим следующий код, который записывает некоторые данные мусора, которые оказались в регистрах ymm0 и ymm1 в 16 МБ статически распределенная WB-память в al oop, состоящая из 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 равно

Подсчитывает общее количество запросов RFO (чтение для владения) в кэш L2. Запросы RFO L2 включают в себя как пропуски RFO запросов L1D, так и предварительные выборки L1D RFO.

, предполагающие, что DCU может выполнять некоторые виды предварительных выборок RFO. Из описания DCU не было ясно из Intel Optimization Manual/2.6.2.4:

Предварительная выборка блока кэша данных (DCU) - эта предварительная выборка, также известная как потоковая предварительная выборка, запускается восходящим доступом к совсем недавно загруженные данные. Процессор предполагает, что этот доступ является частью алгоритма потоковой передачи, и автоматически выбирает следующую строку.

Поэтому я предполагаю, что DCU следует «типу доступа»: если это RFO, то DCU выполняет предварительную выборку RFO.

Все эти предварительные выборки RFO должны go к L2 вместе с запросом RFO, и только некоторые из них (l2_rqsts.rfo_miss) должны go к ядру. offcore_requests.demand_rfo считает только rfo по требованию, но l2_rqsts.rfo_miss учитывает все rfo (по требованию + префектура dcu), что означает соблюдение неравенства offcore_requests.demand_rfo < l2_rqsts.rfo_miss.

ВОПРОС 1: Почему l2_rqsts.rfo_miss намного меньше, чем offcore_requests.demand_rfo (даже l2_rqsts.all_rfo меньше, чем offcore_requests.demand_rfo)

Я ожидал, что спрос offcore_requests.demand_rfo можно сопоставить с offcore_response.demand_rfo.any_response, поэтому для них должно быть приблизительно одинаковое число События основного PMU

ВОПРОС 2: Почему offcore_response.demand_rfo.any_response почти в 1,5 раза больше, чем offcore_requests.demand_rfo?

Я предполагаю, что L2-стример также выполняет некоторые RFO предварительные выборки, но они не должны учитываться в offcore_requests.demand_rfo.


UPD :

$ sudo rdmsr -p 3 0x1A4
1

L2-Streamer off

 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, но все же есть некоторая разница. В документах Intel на OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD я обнаружил следующее:

Примечание. Предварительная выборка, повышенная до спроса, отсчитывается с точки повышения.

Так что я предполагаю, что Предварительные выборки L2 были повышены до Demand и учитывались в запросах offcore Demand. Но это не объясняет разницу между offcore_response.demand_rfo.any_response и offcore_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̶̶̶̶ 1112 * 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-стример выключен: 102 019 160 l2_rqsts.pf_miss + 1 579 107 608 l2_rqsts.rfo_miss = 1 681 126 768; 1 661 232 864 offcore_requests.demand_rfo

Гипотеза также работает, если все предварительные сборщики отключены: 1 684 510 576 l2_rqsts.rfo_miss; 1 684 136 160 offcore_requests.

В случае, если все выключенные ПФ L1-dcache-load-misses приблизительно равны l2_rqsts.rfo_miss, что в свою очередь равно offcore_requests.demand_rfo

То, о чем я до сих пор понятия не имею, почему offcore_response.demand_rfo.any_response имеет гораздо большее значение, чем offcore_requests.demand_rfo

Ответы [ 2 ]

4 голосов
/ 05 марта 2020

Для Вопрос 1 , ответ (по крайней мере на Skylake, но весьма вероятно, будет таким же для озера Виски) состоит в том, что события L2 RFO не учитываются, когда они инициируются предварительной выборкой: не когда инициируется предварительная выборка, и даже когда RFO позже попадает или не попадает в L2. Вы можете посчитать эти события, установив бит предварительной выборки для вашего события (установите 0x10 в umask), и в этом случае вы увидите двойной счет как , описанный здесь .

События, которые вы видите это несколько случайное подмножество RFO, где предварительный выборщик L2 не помог. Счетчики offcore, по-видимому, не имеют такой проблемы: даже если запрос инициируется с помощью предварительной выборки, он может быть преобразован в запрос по требованию, когда запрос достигает обрабатываемого запроса.

Дополнительные сведения можно найти здесь , и вам следует дважды проверить, какие именно события использует ваша версия perf, поскольку Intel изменила определения событий, как описано в последней ссылке.

3 голосов
/ 26 февраля 2020

Мне кажется, что l oop записывает в 2 ^ 18 строк кэша и существует внешняя l oop (не показанная в вопросе), которая выполняет внутреннюю l oop (которая является показано) 6400 раз. Таким образом, ожидаемое общее количество запросов RFO составляет 2 ^ 18 * 6400 = 1 677 721 600, а ожидаемое количество удаленных инструкций хранения - 1677721600 * 2 = 3 355 443 200. Измеренное количество магазинов L1-dcache-stores составляет около 3,410 млрд., Что примерно на 55 млн. Больше, чем ожидалось. Это количество событий должно быть точным, поэтому я предполагаю, что в вопросе присутствует другой код, который не влияет на количество событий. Подсчет событий загрузки также указывает на то, что откуда-то происходит много нагрузок, которые оказывают значительное влияние на счет событий l2_rqsts.all_pf, l2_rqsts.pf_hit, l2_rqsts.pf_miss. Я уже спросил, есть ли в моем комментарии какие-либо существенные фрагменты кода, включенные в измерения.

Из результатов первого эксперимента с включенными всеми средствами предварительной выборки выясняется, что l2_rqsts.rfo_hit + offcore_requests.demand_rfo добавьте к сумме, которая почти равна ожидаемому количеству RFO спроса. Стример L2 может на самом деле предварительно выбирать RFO, как описано в руководстве по оптимизации Intel, в котором объясняется, как может быть l2_rqsts.rfo_hit. Я не знаю, почему l2_rqsts.rfo_miss не равно offcore_requests.demand_rfo. Я думаю, что событие offcore_requests.demand_rfo является точным. Попробуйте отключить только средства предварительной выборки L1D и оставьте их включенными и посмотрите, увеличивается ли время выполнения. Если средства предварительной выборки L1D действительно отправляют какое-либо значительное количество RFO, в L1D должно быть достаточно совпадений при записи, так что это влияет на производительность.

Результаты второго эксперимента с отключенным стримером L2 очень близки к тому, что ожидается. l2_rqsts.rfo_hit очень мало, а l2_rqsts.all_rfo почти равно offcore_requests.demand_rfo, что равно ожидаемому количеству RFO спроса. Это обеспечивает экспериментальное доказательство того, что средства предварительной выборки L1D не выполняют предварительной выборки RFO. l2_rqsts.all_pf в этом случае должно быть равно нулю, поскольку оба средства предварительной выборки L2 отключены.

В последнем эксперименте вы отключили только три из четырех средств предварительной выборки из кэша данных; Вы пропустили предварительную выборку IP-адреса DCU. Счет 2_rqsts.all_rfo в этом случае еще ближе к тому, что исключено. Попробуйте также отключить предварительную выборку IP-адреса DCU и посмотрите, станет ли l2_rqsts.rfo_hit (и, возможно, l2_rqsts.all_pf) нулем.

Ошибка 058 в документе обновления c вашего процессора говорит, что offcore_response.demand_rfo.any_response может пересчитать и вместо него можно использовать offcore_requests.demand_rfo. Это объясняет, почему offcore_response.demand_rfo.any_response больше, чем ожидается во всех экспериментах, а также предполагает, что offcore_requests.demand_rfo является надежным.

...