Условные инструкции в AVX2

Можете ли вы дать список условных инструкций, доступных в AVX2? Пока я нашел следующее:

  • _mm256_blendv_* для выбора из a и b по маске c

Есть ли что-то вроде условного умножения и условного добавления и т. Д.?

Кроме того, если инструкции принимают imm8 (например, _mm256_blend_*), не могли бы вы объяснить, как получить это imm8 после сравнения векторов?


person Serge Rogatch    schedule 23.08.2017    source источник
comment
Все встроенные функции AVX2 здесь. Это то, о чем вы просите в первой части вопроса? Здесь мы не задаем вопросы в виде списка.   -  person Cody Gray    schedule 23.08.2017
comment
@CodyGray, я активно использую эти страницы, но не смог найти ничего, кроме того, что перечислил. Возможно, я что-то упустил. Я ожидаю, что список будет коротким, может быть, 5 пунктов, а может и не больше. Так что я думаю, что вопрос не слишком широкий. И нет необходимости описывать, что делают встроенные функции (это можно прочитать в документации, если я знаю, как их искать). Только как их использовать в принципе как и версии берущие imm8.   -  person Serge Rogatch    schedule 23.08.2017


Ответы (2)


AVX512 вводит необязательную нулевую маскировку и маскировку слияния почти для всех инструкций.

Перед этим, чтобы выполнить условное добавление, замаскируйте один операнд (с vandps или vandnps для инверсии) перед добавлением (вместо vblendvps в результате). Вот почему упакованные инструкции сравнения/внутренние элементы производят элементы со всеми нулями или со всеми единицами.

0.0 является аддитивным элементом идентификации, поэтому его добавление не имеет смысла. (За исключением семантики IEEE -0.0 и +0.0, я забыл, как именно это работает).

Маскирование константного ввода вместо смешивания результата позволяет избежать удлинения критического пути, например, при условном добавлении 1.0.


Условное умножение более громоздко, потому что 0.0 не является мультипликативным тождеством. Вам нужно умножить на 1.0, чтобы сохранить значение неизменным, и вы не можете легко получить это с помощью AND или ANDN с результатом сравнения. Вы можете смешивать входные данные или выполнять умножение и смешивать выходные данные.

Альтернативой blendv является как минимум 3 логических значения, таких как AND/ANDN/OR, но обычно это того не стоит. Хотя обратите внимание, что Haswell запускает vblendvps и vpblendvb как 2 мопов для порта 5, так что это потенциально узкое место по сравнению с использованием целочисленных логических значений, которые могут работать на любом порту. Skylake запускает их vblendvps как 2 мопса для любого порта. Однако может иметь смысл что-то сделать, чтобы избежать появления blendv на критическом пути.

Маскирование входного операнда или смешивание результата — это обычно то, как вы выполняете условные операторы SIMD без ветвления.

BLENDV обычно составляет не менее 2 мопов, поэтому он медленнее, чем AND.

Немедленные смешивания намного эффективнее, но вы не можете их использовать, потому что управление imm8 смешиванием должно быть константой времени компиляции, встроенной в машинный код инструкции. Вот что означает немедленный в контексте языка ассемблера.

person Peter Cordes    schedule 24.08.2017

Руководство Intel Intrinsics предлагает сбор, загрузку и хранение с использованием маски. Непосредственный imm8 в blend_epi16 не программируется, если не рассматривается самомодифицирующийся код или таблица переходов. Все еще возможно получить с помощью pext из BMI2 сжатие половины битов с нечетными позициями из результата movemask — можно получить 32 независимых бита маски из movemask в AVX2, но blend_epi16 использует каждый бит для управления четырьмя байтами — или одним 16-битным переменная в каждом банке.

person Aki Suihkonen    schedule 23.08.2017