Предоставляет ли SSE / AVX средство определения округления результата? - PullRequest
4 голосов
/ 23 октября 2019

Одна из целей бита C1 в слове состояния x87 FPU - показать, был ли округлен неточный результат или нет.

Предоставляет ли SSE / AVX такую ​​индикацию для скалярных операций?

Я не видел подобного бита в регистре MXCSR. Я вынужден использовать инструкции x87, если мне нужна эта информация?

1 Ответ

4 голосов
/ 24 октября 2019

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 их.

...