Итак, вот что я пытаюсь сделать. В моем C ++ проекте это должен быть скомпилирован с Microsoft Visual Studio 2015 или выше, Мне нужно, чтобы какой-то код имел разные версии в зависимости от новейшего набора инструкций SIMD, доступного в ЦП пользователя, среди: SSE
, SSE2
, SSE3
, SSSE3
, SSE4.1
, SSE4.2
, AVX
, AVX2
а также AVX512
,
Так как я ищу в этой точке диспетчеризация процессора во время компиляции, Моим первым предположением было то, что это может быть легко достигнуто с помощью макросов компилятора. Однако, к моему удивлению, было довольно сложно найти информацию о том, как добиться такой загрузки ЦП с помощью макросов в VS2015.
Например, бывший вопросОпределить доступность набора инструкций SSE / SSE2 в Visual Studio«содержит информацию о том, как обнаружить SSE и SSE2 для кода x86, но не для кода x64. Хотя они ссылаются на документ Microsoft: http://msdn.microsoft.com/en-us/library/b0084kay.aspx
Там у нас есть только информация о том, как определить, являются ли SSE, SSE2, AVX и AVX2 включен в компиляторе — не совсем так, поддерживаются ли они процессором. Кроме того, нет ничего общего в других наборах функций, таких как SSE3, SSSE3, SSE4.1, SSE4.2 и AVX512.
Итак, у меня возникает вопрос: как я могу определить, поддерживает ли ЦП пользователя эти наборы функций с помощью макросов, как это делают другие компиляторы, но с Microsoft Visual Studio 2015?
Проблема, с которой вы сталкиваетесь, заключается в том, что Visual Studio исторически предназначен для программного обеспечения. поставщики. Идея, что вы компилируете свое собственное программное обеспечение, просто не входит в ДНК Microsoft.
Практический результат заключается в том, что Microsoft вряд ли заботится о процессоре машины сборки. Это вряд ли процессор, используемый для запуска программного обеспечения.
С другой стороны, это также означает, что Microsoft не страдает от постоянной проблемы Linux, которая заключается в том, что предполагается, что библиотеки системы сборки присутствуют на целевой машине. Сборка на Windows 10 для Windows 7 просто работает.
Компилятор также не позволяет, например, включать до SSE4.1. Вы можете использовать только /arch:avx
или ничего. Кроме того, эта опция только определяет __AVX__
а не обычные макросы вроде __SSSE3__
что gcc / clang / icc определяет, чтобы указать целевую поддержку для предыдущих наборов команд, подразумеваемых AVX.
Других решений пока нет …