Основные процессоры Intel не имеют очень длинных задержек однократных целочисленных команд. На всех портах ALU имеются целочисленные ALU для 1-тактных задержек и конвейерная ALU с 3 циклами. Я думаю, что AMD похожа.
Блок div / sqrt - единственный действительно высокий-Latcy ALU, но целочисленные div / idiv микрокодированы на Intel, так что да, используйте FP, где div / sqrt - это, как правило, однопроцессные инструкции.
целочисленное значение AMD div
/ idiv
- это инструкции по 2 uop (предположительно для записи 2-х выходов), с задержкой, зависящей от данных.
Кроме того, AMD Bulldozer / Piledriver (где 2 целочисленных ядра совместно используют модуль SIMD / FP) имеет довольно высокую задержку для movd xmm, r32
(10c 2 мопов)) и movd r32, xmm
(8с 1 моп). Steamroller сокращает это на 1с каждый. У Райзена есть 3-тактный 1 моп в любом направлении.
movd
в / из регистров XMM дешев на Intel: одиночный моп с 1-тактным (Broadwell и более ранними) или 2-тактным задержкой (Skylake),(https://agner.org/optimize/)
sqrtss
имеет фиксированную задержку (на IvB и более поздних), отличную от возможных с субнормальными входами . Если ваша цепочка с целым числом включает только movd xmm, r32
из произвольного целочисленного битового шаблона, вы можете захотеть установить DAZ / FTZ, чтобы исключить возможность ассистирования FP. Входные данные NaN хороши, это не вызывает замедления для математики SSE / AVX, только x87.
Другие процессоры (Sandybridge и более ранние, и все AMD) имеют переменную задержку sqrtss
, так что вы, вероятно, захотите контролировать начальный битовый шаблон там.
То же самое, если вы хотите использовать sqrtsd
для более высокой задержки на моп, чем sqrtss
. Это все еще переменная задержка даже на Skylake. (15-16 циклов).
Вы можете предположить, что задержка является чистой функциейбитовый шаблон ввода , поэтому запуск цепочки инструкций sqrtss
с одним и тем же вводом каждый раз будет давать одинаковую последовательность задержек или с начальным вводом 0.0
, 1.0
, +inf
,или NaN
, вы получите такую же задержку для eочень в последовательности.
(простые вводы, такие как 1,0 и 0,0 (несколько значащих цифр на входе и выходе), предположительно, работают с самой низкой задержкой. sqrt (1.0) = 1.0 и sqrt (0) = 0, поэтому они являются самосохраняющимися. То же самое для sqrt (NaN) = NaN)
Вы можете использовать and reg, 0
или другое неразрывное обнуление как часть вашей цепочки для управления входным битовым шаблоном . Или возможно or reg, -1
, чтобы создать NaN. Тогда вы можете получить фиксированную задержку на Sandybridge или более ранней версии, а также на AMD, включая Zen.
Или, возможно, pinsrw xmm0, eax, 7
(2 моп для порта 5 на Intel), чтобы изменить только высокое qword XMM, оставив нижнююкак известно 0.0
или 1.0
. Возможно, дешевле всего and
с 0 и использовать movd
, если только давление порта 5 не является проблемой.
Чтобы создать узкое место пропускной способности (не задержка) , ваша лучшая ставка на Skylake - vsqrtpd ymm
- 1 моп для p0, латентность = 15-16, пропускная способность = 9-12.
На Broadwell и ранее это было 3 моп (2p0 p15), но SkylakeЯ думаю, что расширил SIMD делитель (в подготовке к AVX512, я думаю).