Как включить SSE4.1 и SSE3 (но НЕ AVX) в MSVC

Я пытаюсь включить другую поддержку simd с помощью MSVC.

На странице рассказывается о включении некоторых simd, таких как SSE2, AVX, AVX2 https://docs.microsoft.com/en-us/cpp/build/reference/arch-x86?redirectedfrom=MSDN view = vs-2019

Однако в нем не упоминается, как включить другие оптимизации simd, например, SSE4.1, SSE4.2, SSE3. Можно ли включить их без включения AVX?

Кроме того, похоже, что в MSVC2017 / arch: SSE2 больше не поддерживается / не нужен, могу ли я предположить, что SSE3 / SSE4.1 / SSE4.2 также включены по умолчанию?


person knightyangpku    schedule 24.09.2020    source источник
comment
могу ли я предположить, что SSE3 / SSE4.1 / SSE4.2 также включены по умолчанию? - Нет, SSE2 является базовым для x86-64. Каждый процессор x86-64 гарантированно имеет SSE2. Я полагаю, поэтому вам не нужна опция для этого. Но есть некоторые процессоры AMD x86-64 без SSE3 и некоторые процессоры Intel x86-64 без SSE4.1 (например, Core 2 первого поколения).   -  person Peter Cordes    schedule 24.09.2020
comment
Однако я не знаю ответа на ваш вопрос. Вы можете получить SSE4 без AVX только через встроенные функции, потому что MSVC плохо справляется с этим (или разработан на основе модели диспетчеризации времени выполнения, а не времени компиляции), но, возможно, есть опция MSVC. Вы можете использовать компилятор, например clang, где вы можете использовать -O3 -msse4.1 или -O3 -march=penryn   -  person Peter Cordes    schedule 24.09.2020


Ответы (1)


Компилятор VC ++ менее умен, чем вы думаете. Вот как работают эти настройки.

Когда вы создаете 32-битный код и включаете SSE1 или SSE2, он включает автоматическую векторизацию в соответствующие наборы инструкций.

Когда вы создаете 64-битный код, как SSE1, так и SSE2 являются частью набора инструкций, все процессоры AMD64 в мире должны поддерживать оба из них. Вот почему вы получаете предупреждение с / arch: SSE2.

Когда вы настраиваете AVX, компилятор выполняет две функции: включает автоматическую векторизацию в AVX1, а также переключает кодировку инструкций (для всех из них, как SSE, AVX, вручную, так и автоматически векторизованные) с прежней версии на VEX. VEX - хорошая штука, позволяет объединять невыровненные операции чтения RAM с другими инструкциями. Он также решает проблемы с зависимостями, которые могут повлиять на производительность: в кодировке VEX vaddps xmm0, xmm0, xmm1 обнуляются более высокие 16 байтов ymm0, в то время как в устаревшей кодировке addps xmm0, xmm0, xmm1 данные сохраняются.

Когда вы настраиваете AVX2, он выполняет несколько незначительных оптимизаций, особенно такие вещи, как _mm_set1_epi32, могут компилироваться в vpbroadcastd. Также переключает кодировку на VEX, как для AVX1.

Обратите внимание, что я выделил автоматический жирным шрифтом. Компилятор Microsoft не выполняет диспетчеризацию во время выполнения или проверки cpuid, а автоматический векторизатор не использует SSE3 или 4.1. Если вы пишете векторизованный код вручную, компилятор не будет делать откатов, а выдаст все необходимые инструкции. Если параметр AVX / AVX2 присутствует, он влияет только на их кодировку.

Если вы хотите написать вручную векторизованный код, который использует SSE3, SSSE3, SSE 4.1, FMA3, AES, SHA и т. Д., Вам не нужно ничего включать. Вам просто нужно включить соответствующие заголовки и, в идеале, убедиться, что они есть в процессоре во время выполнения. Что касается последней части, я обычно звоню __cpuid < / a> при запуске и проверке этих битов, это должно показать понятное сообщение об ошибке о неподдерживаемом процессоре, вместо жесткого отказа позже.

person Soonts    schedule 25.09.2020