Как включить набор инструкций SSE4.2 в Visual C++?

Я использую дескриптор BRIEF в OpenCV в Visual C++ 2010 для сопоставления точек на двух изображениях.

В статье о BRIEF-дескрипторе написано, что можно ускорить вещи:

«Дескриптор BRIEF использует расстояние Хэмминга, что может быть сделано очень быстро на современных процессорах, которые часто предоставляют специальную инструкцию для выполнения операции XOR или операции подсчета битов, как в случае с последним набором инструкций SSE».

С включенным SSE4.2 он должен быть ускорен. Мои вопросы просто в том, как я это делаю в Visual C++?

Альтернативным способом может быть выбор другого компилятора, поддерживающего SSE4. Например, ICC от Intel. Это действительно необходимо?


person Fredrik    schedule 17.04.2012    source источник
comment
Знаете ли вы разницу между Visual Studio (IDE) и Visual C++ (язык программирования)? :)   -  person abatishchev    schedule 17.04.2012


Ответы (2)


К сожалению, это так не работает.

Компилятору C/C++ можно указать использовать определенный набор инструкций в проекте-> C/C++ -> Генерация кода-> Включить расширенный набор инструкций. Но он почти ничего не делает, а в вашем случае абсолютно ничего. Это связано с тем, что некоторые инструкции процессора не могут быть легко доступны из операторов C. Некоторые компиляторы (например, Intel) лучше справляются с этим, чем другие, но для того, чего вы хотите достичь, ни один компилятор не является достаточно умным.

Что вам нужно сделать, так это найти конкретный алгоритм, изучить инструкции SSE и переписать алгоритм с эти инструкции вручную. Вы можете писать на чистом ассемблере или использовать внутренние функции, которые могут быть вызывается из C/C++ и выдает инструкции SSE при компиляции.

person Sam    schedule 17.04.2012
comment
Хорошая библиотека C++, такая как libstdc++ (типичная для GNU/Linux) или более новая libc++, будет использовать popcnt для реализации std::bitset<64>::count(), когда она гарантированно доступна во время компиляции. Но MSVC разработан на основе модели одного двоичного файла, который выполняет диспетчеризацию во время выполнения, и его библиотека может не иметь такой оптимизации даже для -arch:AVX (что подразумевает SSE4.2 и, следовательно, popcnt), поэтому на практике этот ответ, вероятно, подходит для MSVC. - person Peter Cordes; 15.02.2021

Компилятор MSVC имеет параметр /arch для указания минимальной архитектуры, на которую должна ориентироваться ваша программа. Установка его как /arch:SSE2 сообщит компилятору, что ЦП поддерживает инструкции SSE2, и он будет автоматически использовать их всякий раз, когда оптимизатор решит, что это уместно.

Однако в MSVC нет опций /arch:SSE4 или /arch:SSE42. Взглянув на реализацию стандартной библиотеки, можно предположить, что /arch:AVX или /arch:AVX2 также подразумевает SSE4.2. Например, реализация MSVC библиотечной функции C++20 std::popcount выполнит проверку процессора во время выполнения, чтобы узнать, может ли он использовать инструкцию popcnt SSE4.2. Но если вы ориентируетесь на AVX, он пропускает проверку во время выполнения и просто предполагает, что процессор его поддерживает.

Я думаю, что gcc и clang имеют определенные параметры для включения SSE4 и SSE4.2. Обновление: Питер Кордес подтверждает в комментариях: чтобы конкретно включить popcnt, -mpopcnt или для SSE4.2 -msse4.2, что подразумевает popcnt.

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

person Adrian McCarthy    schedule 14.02.2021
comment
Для GCC/clang: -march=nehalem или новее, или -march=znver1 (Zen) включит наборы инструкций, поддерживаемые этими ЦП (и настроенные на тот, который вы укажете), который включает popcnt. Или -march=native. Чтобы конкретно включить popcnt, -mpopcnt или для SSE4.2 -msse4.2, что подразумевает popcnt. - person Peter Cordes; 15.02.2021
comment
Рад слышать, что у MSVC есть некоторая поддержка CPU-функций для popcnt в std::popcount. Он также раскрывает это через std::bitset<64>::count(), что является стандартным способом получить оптимизированный для платформы popcount? - person Peter Cordes; 15.02.2021
comment
@PeterCordes: я специально не смотрел на std::bitset, но был бы удивлен, если бы он не использовал преимущества popcnt. Изучив реализацию std::popcount, я убедился, что в сгенерированном коде используется popcnt (и что /arch:AVX устраняет проверку во время выполнения и откат) с помощью Godbolt Compiler Explorer. Должно быть просто сделать то же самое для std::bitset. - person Adrian McCarthy; 16.02.2021