Проблемы с пониманием и сравнение показателей производительности процессора - PullRequest
0 голосов
/ 23 февраля 2019

При запуске toplev из pmu-tools на программном обеспечении (скомпилированном с помощью gcc: gcc -g -O3) я получаю такой вывод:

FE             Frontend_Bound:                                          37.21 +-     0.00 % Slots                
BAD            Bad_Speculation:                                         23.62 +-     0.00 % Slots                
BE             Backend_Bound:                                            7.33 +-     0.00 % Slots below          
RET            Retiring:                                                31.82 +-     0.00 % Slots below          
FE             Frontend_Bound.Frontend_Latency:                         26.55 +-     0.00 % Slots                
FE             Frontend_Bound.Frontend_Bandwidth:                       10.62 +-     0.00 % Slots                
BAD            Bad_Speculation.Branch_Mispredicts:                      23.72 +-     0.00 % Slots                
BAD            Bad_Speculation.Machine_Clears:                           0.01 +-     0.00 % Slots below          
BE/Mem         Backend_Bound.Memory_Bound:                               1.59 +-     0.00 % Slots below          
BE/Core        Backend_Bound.Core_Bound:                                 5.73 +-     0.00 % Slots below          
RET            Retiring.Base:                                           31.54 +-     0.00 % Slots below          
RET            Retiring.Microcode_Sequencer:                             0.28 +-     0.00 % Slots below          
FE             Frontend_Bound.Frontend_Latency.ICache_Misses:            0.70 +-     0.00 % Clocks below         
FE             Frontend_Bound.Frontend_Latency.ITLB_Misses:              0.62 +-     0.00 % Clocks below         
FE             Frontend_Bound.Frontend_Latency.Branch_Resteers:          5.04 +-     0.00 % Clocks_Estimated      <==
FE             Frontend_Bound.Frontend_Latency.DSB_Switches:             0.57 +-     0.00 % Clocks below         
FE             Frontend_Bound.Frontend_Latency.LCP:                      0.00 +-     0.00 % Clocks below         
FE             Frontend_Bound.Frontend_Latency.MS_Switches:              0.76 +-     0.00 % Clocks below         
FE             Frontend_Bound.Frontend_Bandwidth.MITE:                   0.36 +-     0.00 % CoreClocks below     
FE             Frontend_Bound.Frontend_Bandwidth.DSB:                   26.79 +-     0.00 % CoreClocks below     
FE             Frontend_Bound.Frontend_Bandwidth.LSD:                    0.00 +-     0.00 % CoreClocks below     
BE/Mem         Backend_Bound.Memory_Bound.L1_Bound:                      6.53 +-     0.00 % Stalls below         
BE/Mem         Backend_Bound.Memory_Bound.L2_Bound:                     -0.03 +-     0.00 % Stalls below         
BE/Mem         Backend_Bound.Memory_Bound.L3_Bound:                      0.37 +-     0.00 % Stalls below         
BE/Mem         Backend_Bound.Memory_Bound.DRAM_Bound:                    2.46 +-     0.00 % Stalls below         
BE/Mem         Backend_Bound.Memory_Bound.Store_Bound:                   0.22 +-     0.00 % Stalls below         
BE/Core        Backend_Bound.Core_Bound.Divider:                         0.01 +-     0.00 % Clocks below         
BE/Core        Backend_Bound.Core_Bound.Ports_Utilization:              28.53 +-     0.00 % Clocks below         
RET            Retiring.Base.FP_Arith:                                   0.02 +-     0.00 % Uops below           
RET            Retiring.Base.Other:                                     99.98 +-     0.00 % Uops below           
RET            Retiring.Microcode_Sequencer.Assists:                     0.00 +-     0.00 % Slots_Estimated below
               MUX:                                                    100.00 +-     0.00 %                      
warning: 6 results not referenced: 67 71 72 85 87 88

Этот двоичный файл занимаетоколо 4,7 секунды для запуска.

Если я добавлю следующий флаг в gcc: -falign-loops = 32, бинарному файлу теперь потребуется около 3,8 секунды для запуска, и это вывод из toplev:

FE             Frontend_Bound:                                          17.47 +-     0.00 % Slots below           
BAD            Bad_Speculation:                                         28.55 +-     0.00 % Slots                 
BE             Backend_Bound:                                           12.02 +-     0.00 % Slots                 
RET            Retiring:                                                34.21 +-     0.00 % Slots below           
FE             Frontend_Bound.Frontend_Latency:                          6.10 +-     0.00 % Slots below           
FE             Frontend_Bound.Frontend_Bandwidth:                       11.31 +-     0.00 % Slots below           
BAD            Bad_Speculation.Branch_Mispredicts:                      29.19 +-     0.00 % Slots                  <==
BAD            Bad_Speculation.Machine_Clears:                           0.01 +-     0.00 % Slots below           
BE/Mem         Backend_Bound.Memory_Bound:                               4.58 +-     0.00 % Slots below           
BE/Core        Backend_Bound.Core_Bound:                                 7.44 +-     0.00 % Slots below           
RET            Retiring.Base:                                           33.70 +-     0.00 % Slots below           
RET            Retiring.Microcode_Sequencer:                             0.50 +-     0.00 % Slots below           
FE             Frontend_Bound.Frontend_Latency.ICache_Misses:            0.55 +-     0.00 % Clocks below          
FE             Frontend_Bound.Frontend_Latency.ITLB_Misses:              0.58 +-     0.00 % Clocks below          
FE             Frontend_Bound.Frontend_Latency.Branch_Resteers:          5.72 +-     0.00 % Clocks_Estimated below
FE             Frontend_Bound.Frontend_Latency.DSB_Switches:             0.17 +-     0.00 % Clocks below          
FE             Frontend_Bound.Frontend_Latency.LCP:                      0.00 +-     0.00 % Clocks below          
FE             Frontend_Bound.Frontend_Latency.MS_Switches:              0.40 +-     0.00 % Clocks below          
FE             Frontend_Bound.Frontend_Bandwidth.MITE:                   0.68 +-     0.00 % CoreClocks below      
FE             Frontend_Bound.Frontend_Bandwidth.DSB:                   42.01 +-     0.00 % CoreClocks below      
FE             Frontend_Bound.Frontend_Bandwidth.LSD:                    0.00 +-     0.00 % CoreClocks below      
BE/Mem         Backend_Bound.Memory_Bound.L1_Bound:                      7.60 +-     0.00 % Stalls below          
BE/Mem         Backend_Bound.Memory_Bound.L2_Bound:                     -0.04 +-     0.00 % Stalls below          
BE/Mem         Backend_Bound.Memory_Bound.L3_Bound:                      0.70 +-     0.00 % Stalls below          
BE/Mem         Backend_Bound.Memory_Bound.DRAM_Bound:                    0.71 +-     0.00 % Stalls below          
BE/Mem         Backend_Bound.Memory_Bound.Store_Bound:                   1.85 +-     0.00 % Stalls below          
BE/Core        Backend_Bound.Core_Bound.Divider:                         0.02 +-     0.00 % Clocks below          
BE/Core        Backend_Bound.Core_Bound.Ports_Utilization:              17.38 +-     0.00 % Clocks below          
RET            Retiring.Base.FP_Arith:                                   0.02 +-     0.00 % Uops below            
RET            Retiring.Base.Other:                                     99.98 +-     0.00 % Uops below            
RET            Retiring.Microcode_Sequencer.Assists:                     0.00 +-     0.00 % Slots_Estimated below 
               MUX:                                                    100.00 +-     0.00 %                       
warning: 6 results not referenced: 67 71 72 85 87 88

При добавлении этого флага латентность внешнего интерфейса улучшилась (как мы можем видеть из вывода toplev).Я понимаю, что, добавив этот флаг, теперь циклы выравниваются по 32 байта, и DSB чаще срабатывает при выполнении сжатых циклов (код тратит свое время в основном на пару небольших циклов).Однако я не понимаю, почему метрика Frontend_Bound.Frontend_Bandwidth.DSB увеличилась (описание для этой метрики: «Эта метрика представляет базовую долю циклов, в которых ЦП, вероятно, был ограничен из-за конвейера выборки DSB (декодированный кэш мопов)»).Я бы ожидал, что этот показатель снизится, поскольку использование DSB - это именно то, что я улучшаю, добавив флаг gcc.

PS: при запуске toplev я использовал --no-multiplex,минимизировать ошибки, вызванные мультиплексированием.Целевая архитектура - Broadwell, а сборка циклов следующая (синтаксис Intel):

 606:   eb 15                   jmp    61d <main+0x7d>
 608:   0f 1f 84 00 00 00 00    nop    DWORD PTR [rax+rax*1+0x0]
 60f:   00 
 610:   48 83 c6 01             add    rsi,0x1
 614:   48 81 fe 01 20 00 00    cmp    rsi,0x2001
 61b:   74 ad                   je     5ca <main+0x2a>
 61d:   41 80 3c 30 00          cmp    BYTE PTR [r8+rsi*1],0x0
 622:   74 ec                   je     610 <main+0x70>
 624:   48 8d 0c 36             lea    rcx,[rsi+rsi*1]
 628:   48 81 f9 00 20 00 00    cmp    rcx,0x2000
 62f:   77 20                   ja     651 <main+0xb1>
 631:   0f 1f 44 00 00          nop    DWORD PTR [rax+rax*1+0x0]
 636:   66 2e 0f 1f 84 00 00    nop    WORD PTR cs:[rax+rax*1+0x0]
 63d:   00 00 00 
 640:   41 c6 04 08 00          mov    BYTE PTR [r8+rcx*1],0x0
 645:   48 01 f1                add    rcx,rsi
 648:   48 81 f9 00 20 00 00    cmp    rcx,0x2000
 64f:   7e ef                   jle    640 <main+0xa0>

1 Ответ

0 голосов
/ 24 февраля 2019

Ваш код сборки показывает, почему метрика DSB пропускной способности очень высока (т. Е. В 42,01% всех циклов ядра, в которых DSB активен, DSB выдает менее 4 моп).Кажется, проблема существует в следующем цикле:

 610:   48 83 c6 01             add    rsi,0x1
 614:   48 81 fe 01 20 00 00    cmp    rsi,0x2001
 61b:   74 ad                   je     5ca <main+0x2a>
 61d:   41 80 3c 30 00          cmp    BYTE PTR [r8+rsi*1],0x0
 622:   74 ec                   je     610 <main+0x70>

Этот цикл выравнивается по 16-байтовой границе, несмотря на передачу -falign-loops=32 компилятору.Также последняя инструкция пересекает 32-байтовую границу, что означает, что она будет сохранена в другом наборе кэша в DSB.DSB может доставлять мопы в IDQ только из одного набора в одном и том же цикле.Таким образом, он доставит add и cmp/je в одном цикле, а второй cmp/je в следующем цикле.В обоих циклах ширина полосы DSB составляет менее 4 моп.

Однако предполагается, что LSD скрывает такие ограничения.Но похоже, что он не активен.Цикл содержит две инструкции перехода.Первый, кажется, проверяет, был ли достигнут размер массива (0x2001 байт), а второй, кажется, проверяет, был ли достигнут ненулевой байтовый элемент.Максимальное количество отключений 0x2001 дает достаточно времени для LSD, чтобы обнаружить петлю и заблокировать ее в IDQ.С другой стороны, если вероятность того, что ненулевой элемент найден до того, как LSD обнаружит петлю, то мопы будут либо доставлены с пути DSB, либо с пути MITE.В этом случае кажется, что они доставляются с пути DSB.И поскольку тело цикла пересекает 32-байтовую границу, для выполнения одной итерации требуется 2 цикла (по сравнению с максимумом одного цикла, если цикл был выровнен по 32 байта, поскольку в Broadwell имеется два порта выполнения перехода).Я думаю, что если вы выровняете этот цикл с 32 байтами, показатель DSB пропускной способности улучшится не потому, что DSB будет доставлять 4 мопа за такт (он будет доставлять только 3 мопа за такт), а потому, что для выполнения может потребоваться меньшее количество тактовцикл.

Даже если вы каким-то образом изменили код так, чтобы вместо этого лупы доставлялись из LSD, вы все равно не можете сделать лучше, чем 1 цикл на итерацию, несмотря на то, что LSD в Broadwell может доставлять мопычерез итерации цикла (в отличие от DSB, я думаю).Это потому, что вы столкнетесь с другим узким местом: в одном цикле может быть выделено не более двух прыжков (см .: Может ли LSD выдавать uOP с следующей итерации обнаруженного цикла? ).Таким образом, метрика LSD полосы пропускания станет больше, а метрика DSB полосы пропускания станет меньше.Это просто меняет узкое место, но не улучшает производительность (хотя может улучшить энергопотребление).Нет никакого способа улучшить полосу пропускания внешнего интерфейса этого цикла, кроме перемещения работы из некоторого места в цикл.

Информацию о LSD см. В Почему jnz требуется 2 цикла для завершения во внутреннем цикле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...