SSE / AVX не предоставляют аппаратную поддержку для обнаружения этого, даже для скалярных инструкций, таких как addss
. SSE был разработан для SIMD с 4 числами с плавающей запятой на вектор XMM, и, вероятно, Intel не хотела предоставлять битовую карту из 4 битов в MXCSR. Хотя это был бы возможный выбор дизайна.
Как отмечает @Mysticial в комментариях, его можно рассчитать, используя дополнительные инструкции.
(непроверенная идея, которая можетто, что вы хотите. Я думаю, что это должно работать даже с субнормальными значениями и т. д .; сравнение для точного равенства такое же, как битовое сравнение, за исключением -0.0 == +0.0 или для NaN)
С AVX512 вы можетевыполните обычные вычисления add / sub / mul / div / sqrt (с округлением по умолчанию), затем снова с переопределением режима округления для усечения до 0. Используйте vcmpps
для равенства результатов. Элементы, которые сравниваются точно одинаково, были округлены до 0 в режиме округления по умолчанию (или были точными оба раза). Разумеется, вы можете использовать в качестве переопределения значение -Inf для + Inf в качестве переопределения вместо 0.
Префикс EVEX AVX512 может кодировать переопределение режима округления для каждой инструкции без изменения MXCSR. Это позволяет эффективно сделать это, значительно более эффективно, чем изменение MXCSR. например, _mm512_add_round_ps (__m512 a, __m512 b, int);
. Обратите внимание, что встроенное округление AVX512 (er
) доступно только для 512-битных векторов;к сожалению, вы не можете использовать его с AVX512VL для выполнения переопределений округления 256-битных векторов, чтобы избежать текущих максимальных турбо и других недостатков использования 512-битных векторов в современных процессорах семейства Skylake. При использовании ER также применяется SAE (подавление всех исключений), что означает, что инструкция вообще не должна обновлять MXCSR. Кодировка инструкций AVX-512 - {er} Значение .
В синтаксисе asm, rz
= округлить до нуля. Смотрите таблицу 2-36. EVEX Embedded Broadcast / Rounding / SAE и Vector Length on Vector Vector в руководстве Intel vol.2 x86 .
vaddpd zmm2, zmm1, zmm0 ; no override, or {rne-sae} would be Nearest-Even
vaddpd zmm3, zmm1, zmm0, {rz-sae} ; rounding = truncation toward Zero
vcmpneqpd k1, zmm2, zmm3 ; compare for not-equal
;;; k1 = bitmask
;; 0 means rounded toward 0 or exact
;; 1 means rounded away from 0
Если вам не нужен основной результат 512-битовый вектор, вы можете сделать это и сравнить с регистрами XMM или YMM, но операция {rz-sae}
должна быть ZMM. Сравнение YMM дает возможность сравнения в другой регистр YMM (AVX1), а не в регистр маски AVX512. Но если вы используете AVX512, регистры маски обычно довольно хороши.
Для этого всегда нужны 2 дополнительные инструкции: повторение операции и сравнение. Предложение Mysticial использовать FMA после mulps
может избежать этого, если вы просто используете знаковый бит напрямую вместо сравнения с нулем. например, vmovmskps
, чтобы получить целочисленное растровое изображение, или vxorps
или vandps
, чтобы объединить некоторые векторы, где "истинное значение", о котором вы заботитесь, является знаковым битом. Это может быть вход для vblendvps
(который также учитывает только биты знака) или для возможного vmovmskps
.
Изменение режима округления без AVX512 может не быть полной катастрофой, особенноесли вы можете сделать несколько векторов по умолчанию, прежде чем перейти к усечению и повторить их. То, что может сделать его более эффективным, чем последовательность обнаружения направления округления, которая принимала 3 или более команд на вектор, если у вас достаточно регистров для воспроизведения, чтобы амортизировать изменения MXCSR в течение достаточного количества операций.
Очевидно, что некоторые процессоры Intel переименовывают MXCSR;событие perf для циклов остановки переименования MXCSR существует в некоторой микроархитектуре (не знаю, какая именно):
Задержки из-за переименования регистра MXCSR, происходящего слишком близко к предыдущему переименованию MXCSR.
Таким образом, его изменение не должно приводить к потере планировщика, но это не здорово. И в соответствии с этой формулировкой, изменить его дважды рядом может быть плохо. IDK, если есть только ограниченное количество физических записей MXCSR для переименования, или какая-то другая причина для этого ограничения.
Конечно, в цикле вы не сохраните , переворачиваниеи перезагрузите значения MXCSR;у вас есть два значения MXCSR в памяти и просто ldmxcsr
их.