Ваш код сборки показывает, почему метрика 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 цикла для завершения во внутреннем цикле.