У меня есть алгоритм обработки изображений, который я реализовал в трех версиях:
- Использование набора команд x64 (rax, rbx, ... registers)
- Использование набора инструкций SSE(регистры xmm)
- Использование набора инструкций AVX2 (регистры ymm)
Производительность улучшается с каждым шагом оптимизации.Однако мне нужно запустить его на старых процессорах, которые поддерживают только SSE (я использую платформу x64 на Visual Studio, поэтому все мои процессоры поддерживают SSE).
В Visual Studio есть параметр, который называется «Включить расширенное».Instruction Set ", который я должен установить на /arch:AVX2
, чтобы получить лучшую производительность на моих новых процессорах.Однако с этим параметром исполняемый файл вылетает на моих старых процессорах.Если я установлю «Включить расширенный набор инструкций» на /arch:SSE2
, то мой исполняемый файл будет работать на старых процессорах, но я не получу максимальную производительность на новых процессорах.
Я измерил скорость выполнения для всех комбинаций флагов компилятораи наборы инструкций, используя мой новый процессор.Сводка приведена в следующей таблице.
Instruction set || Compilation flags
which I use || /arch:SSE /arch:AVX2
----------------++------------------------------------
x64 || bad (4.6) bad (4.5)
SSE || OK (1.9) bad (5.3)
AVX2 || bad (3.2) good (1.4)
Мой векторизованный код использует встроенные функции, например:
// AVX2 - conversion from 32-bit to 16-bit
temp = _mm256_packus_epi32(input[0], input[1]);
output = _mm256_permute4x64_epi64(temp, 0xd8);
// SSE - choosing one of two results using a mask
result = _mm_blendv_epi8(result0, result1, mask);
Я предполагаю, что если Visual Studio получит компиляцию /arch:AVX2
флаг, он выполняет все необходимые оптимизации для AVX2, например, испуская vzeroupper
.Так что я не вижу, как можно добиться максимальной производительности на обоих типах процессоров с одним и тем же скомпилированным исполняемым файлом.
Возможно ли это?Если да, какие флаги компиляции мне нужно передать компилятору Visual Studio?