Почему некоторые задержки Haswell AVX рекламируются Intel как 3 раза медленнее, чем Sandy Bridge?

В Intel intrinsics webapp несколько операций, похоже, ухудшились от Sandy Bridge до Haswell. Например, многие операции ввода, такие как _mm256_insertf128_si256, показывают таблицу затрат следующим образом:

   Performance
 Architecture   Latency   Throughput
 Haswell        3         -
 Ivy Bridge     1         - 
 Sandy Bridge   1         - 

Я нашел эту разницу загадочной. Разве это отличие, потому что есть новые инструкции, которые заменяют эти или что-то, что компенсирует это (какие)? Кто-нибудь знает, изменит ли Skylake эту модель?

Ответ 1

TL: DR: все переходы/вставки/экстракты пересечения полосы пропускания имеют задержку 3 с на Haswell/Skylake, но 2c латентность на SnB/IvB, согласно Проверка Agner Fog.

Это, вероятно, 1c в исполнительном модуле + неизбежная байпасная задержка какого-то типа, потому что фактические исполнительные блоки в SnB через Broadwell имеют стандартизированные задержки 1, 3 или 5 циклов, никогда 2 или 4 цикла. (SKL делает несколько uops uops 4c, включая FMA/ADDPS/MULPS).

(Обратите внимание, что на процессорах AMD, которые делают AVX1 с 128b ALU (например, Bulldozer/Piledriver/Steamroller), insert128/extract128 намного быстрее, чем перетасовки, такие как VPERM2F128.)


В руководстве по интригам иногда есть поддельные данные. Я предполагаю, что это означает, что для reg-reg-формы инструкций, за исключением случаев, связанных с нагрузкой. Даже когда это правильно, руководство по интригам не дает очень подробного представления о производительности; см. ниже для обсуждения таблиц/направляющих Agner Fog.


(Один из моих любимых мошенников с intrinsics заключается в том, что трудно использовать PMOVZX/PMOVSX в качестве нагрузки, потому что только входящие внутри него строки принимают источник __m128i, хотя pmovzxbd загружает только 4B или 8B (ymm).Это и/или широковещательные нагрузки (_mm_set1_* с AVX1/2) - отличный способ сжать константы в памяти. Должны быть внутренние, которые принимают const char* (потому что это позволяло псевдонимам)).


В этом случае измерения Agner Fog показывают, что SnB/IvB имеет задержку 2 с для reg-reg vinsertf128/vextractf128, в то время как его измерения для Haswell (3c latency, one per 1c tput) согласуются с таблицей Intel. Таким образом, это еще один случай, когда цифры в руководстве Intel intrinsics неверны. Это отлично подходит для поиска правильного внутреннего, но не хорошего источника для надежных номеров производительности.. Он ничего не говорит о портах выполнения или общих командах и часто пропускает даже номера пропускной способности. Задержка часто не является ограничивающим фактором в векторном целочисленном коде. Вероятно, именно поэтому Intel допустила задержки для Haswell.

Форма reg-mem существенно отличается. vinsertf128 y,y,m,i имеет значение lat/recip-tput: IvB: 4/1, Haswell/BDW: 4/2, SKL: 5/0.5. Он всегда является инструкцией 2-uop (объединенный домен), используя один ALU uop. IDK, почему пропускная способность настолько отличается. Возможно, Agner тестировался несколько иначе?

Интересно, что vextractf128 mem,reg, i не использует никаких ALU-шумов. Это команда 2-fused-domain-uop, которая использует только порты store-data и store-address, а не блок перетасовки. (Таблица Agner Fog перечисляет его как использование одного p015 uop на SnB, 0 на IvB. Но даже на SnB нет метки в каком-либо конкретном столбце, поэтому IDK, который является правильным.)

Это глупо, что vextractf128 тратит байт на непосредственный операнд. Думаю, они не знали, что они собираются использовать EVEX для следующего расширения длины вектора и готовились к немедленному переходу с 0..3. Но для AVX1/2 вы никогда не должны использовать эту инструкцию с немедленным = 0. Вместо этого просто movups mem, xmm или movaps xmm,xmm. (Я думаю, что компиляторы знают это и делают это, когда вы используете внутреннее значение с index = 0, как это делают для _mm_extract_epi32 и т.д. (movd).)


Задержка чаще всего является фактором кода FP, а Skylake - монстром для ALU FP. Им удалось отбросить задержку для FMA до 4 тактов, поэтому mulps/addps/fma... ps - это все 4 c латентность с одной на пропускную способность 0,5 c. (Broadwell - mulps/addps = 3c latency, fma = 5c latency. Haswell - addps = 3c latency, mul/fma = 5c). Skylake сбросил отдельный блок добавления, так что addps фактически ухудшились с 3c до 4c, но с удвоенной пропускной способностью. (Haswell/BDW только добавляли addps с одной на 1 c пропускную способность, вдвое меньше, чем mul/fma.) Таким образом, с использованием многих векторных аккумуляторов важно в большинстве алгоритмов FP для сохранения 8 или 10 FMA в полете сразу насытить пропускную способность, если есть зависимость от цикла. В противном случае, если тело цикла достаточно мало, выполнение вне очереди будет иметь несколько итераций в полете сразу.

Операторы Integer in-lane обычно имеют только задержку в 1 c, поэтому вам нужно намного меньше parallelism, чтобы максимизировать пропускную способность (и не ограничиваться задержкой).


Ни один из других вариантов получения данных в/из верхней половины ymm не лучше

vperm2f128 или AVX2 vpermps стоят дороже. Прохождение через память приведет к сбою в работе магазина → большая латентность для вставки (2 узких магазина → широкая нагрузка), поэтому это явно плохо. Не пытайтесь избегать vinsertf128 в тех случаях, когда это полезно.

Как всегда, попробуйте использовать самые дешевые последовательности команд. например для горизонтальной суммы или другого сокращения всегда сводятся к вектору 128b сначала, потому что перекрестные переходы медленны. Обычно это просто vextractf128/addps xmm, затем обычный горизонтальный 128b.

В качестве Mystical намечено, Haswell, а затем половина полоса пропускания вектора перетасовки SnB/IvB для векторов 128b. SnB/IvB может pshufb/pshufd с одним на пропускную способность 0,5 c, но только один на 1c для shufps (даже версия 128b); то же самое для других тасов, которые имеют версию ymm в AVX1 (например, vpermilps, которая, по-видимому, существует только так, что FP load-and-shuffle может быть выполнена в одной инструкции). Хасуэлл полностью избавился от блока таблеток 128b на порту1, вместо того, чтобы расширять его для AVX2.


re: skylake

Таблицы Agner Fog/insn были обновлены в декабре, включив Skylake. См. Также x86 теги wiki для других ссылок, Reg, reg form имеет ту же производительность, что и в Haswell/Broadwell.