Документация Intel, в которой говорится, что «не нужны, поскольку они автоматически генерируются компилятором», на самом деле верна. И все же это неудовлетворительно.
Но чтобы понять, почему это так, нужно взглянуть на историю AVX512. Хотя ни одна из этих сведений не является официальной, она явно основана на доказательствах.
Причина, по которой состояние внутренних масок попало в беспорядок, в котором они сейчас находятся, вероятно, состоит в том, что AVX512 был «развернут» в несколько этапов без достаточного предварительного планирования до следующего этапа.
Этап 1. Приземление рыцарей
В Knights Landing добавлены 512-битные регистры, которые имеют только 32-битную и 64-битную детализацию данных. Следовательно, регистры маски никогда не должны быть шире 16 бит.
Когда Intel разрабатывала этот первый набор встроенных функций AVX512, они пошли дальше и добавили встроенные функции почти для всего, включая регистры маски. Вот почему внутренние функции маски, которые существуют, имеют всего 16 бит. И они охватывают только инструкции, существующие в Knights Landing. (хотя я не могу объяснить, почему отсутствует KSHIFT
)
В Knights Landing операции с маской были быстрыми (2 цикла). Но перемещение данных между регистрами маски и регистрами общего назначения было очень медленным (5 циклов). Таким образом, имело значение, где выполняются операции с масками, и имело смысл дать пользователю более детальный контроль над перемещением материала назад и вперед между регистрами маски и георадаром.
Этап 2: Скайлейк Перли
Skylake Purley расширяет AVX512, чтобы покрыть полосы с побайтовым разбиением. И это увеличило ширину регистров маски до полных 64 бит. Во втором раунде также были добавлены KADD
и KTEST
, которых не было в Knights Landing.
Эти новые инструкции маски (KADD
, KTEST
и 64-битные расширения существующих) - это те, которые не имеют своих внутренних аналогов.
Хотя мы не знаем точно, почему они отсутствуют, есть веские доказательства в поддержку этого:
Компилятор / синтаксис:
В Knights Landing одинаковые внутренние свойства маски использовались как для 8-битных, так и для 16-битных масок. Их невозможно было различить. Расширение их до 32-битных и 64-битных усугубило беспорядок. Другими словами, Intel изначально неправильно спроектировала внутренние компоненты маски. И они решили отказаться от них полностью, а не исправлять.
Несоответствие производительности:
Инструкции по маске пересечения битов на Skylake Purley медленные. В то время как все побитовые инструкции являются однократными, KADD
, KSHIFT
, KUNPACK
и т. Д. - все 4 цикла. Но переход между маской и георадаром составляет всего 2 цикла.
Из-за этого часто бывает быстрее переместить их в георадары, чтобы сделать их и переместить обратно. Но вряд ли программист этого знает. Таким образом, вместо того, чтобы предоставить пользователю полный контроль над регистрами масок, Intel предпочла, чтобы это решение принимал компилятор.
Если заставить компилятор принять это решение, это означает, что у компилятора должна быть такая логика. В настоящее время компилятор Intel генерирует kadd
и семейство в определенных (редких) случаях. Но GCC этого не делает. В GCC все операции с масками, кроме самых простых, будут перенесены в GPR и будут выполняться там.
Последние мысли:
Перед выпуском Skylake Purley я лично написал много кода AVX512, который включает много кода маски AVX512. Они были написаны с определенными предположениями о производительности (задержка одного цикла), которые оказались ложными на Skylake Purley.
Судя по моему собственному тестированию на Skylake X, некоторые из моих встроенных в маску кодов, которые полагались на операции пересечения битов, оказались медленнее, чем версии, созданные компилятором, которые переместили их в GPR и обратно. Причина, конечно, в том, что KADD
и KSHIFT
были 4 цикла вместо 1.
Конечно, я предпочитаю, чтобы Intel действительно предоставляла встроенные функции, чтобы дать нам контроль, который я хочу. Но здесь очень легко ошибиться (с точки зрения производительности), если вы не знаете, что делаете.
Обновление:
Неясно, когда это произошло, но в последней версии Intel Intrinsics Guide есть новый набор встроенных масок с новым соглашением об именах, которое охватывает все инструкции и ширину. Эти новые внутренние свойства заменяют старые.
Так что это решает всю проблему. Хотя степень поддержки компилятора все еще неизвестна.
Примеры:
_kadd_mask64()
_kshiftri_mask32()
_cvtmask16_u32()
заменяет _mm512_mask2int()
person
Mysticial
schedule
18.07.2017
kmov
в / из целочисленных регистров, вероятно, также использует этот порт, поэтому переход к целочисленному и обратно за один сдвиг по-прежнему глуп для пропускной способности, если не для задержки). - person Peter Cordes   schedule 23.08.2017ktest
позволяет объединить макросtest/jcc
для-march=skylake-AVX512
. Это просто тупо для-march=knl
. - person Peter Cordes   schedule 23.08.2017ktest+jcc
vskmov+test/jcc
? - person zinga   schedule 25.08.2017ktest
+jcc
- это 2 или 3 мопса. Надеюсь,ktest
равно 1, но SSE / AVXptest
- 2 мупа (1 для теста, 1 для перемещения результата из векторного домена в целое число, тот же порт, что иmovd
).kmov
+test/jcc
почти наверняка всего 2 мупа. - person Peter Cordes   schedule 25.08.2017