Какие файлы заголовков предоставляют встроенные функции для различных расширений набора инструкций SIMD x86 (MMX, SSE, AVX, ...)? В сети такой список найти невозможно. Поправьте меня если я ошибаюсь.
источник
Какие файлы заголовков предоставляют встроенные функции для различных расширений набора инструкций SIMD x86 (MMX, SSE, AVX, ...)? В сети такой список найти невозможно. Поправьте меня если я ошибаюсь.
В наши дни вы обычно должны просто включать <immintrin.h>
. Он включает в себя все.
GCC и clang остановят вас от использования встроенных функций для инструкций, которые вы не включили во время компиляции (например, с помощью -march=native
или-mavx2 -mbmi2 -mpopcnt -mfma -mcx16 -mtune=znver1
или что-то еще.)
MSVC и ICC позволят вам использовать встроенные функции без включения чего-либо во время компиляции, но вы все равно должны включить AVX перед использованием встроенных функций AVX.
Исторически (до того, как immintrin.h
втягивать все) вам приходилось вручную включать заголовок для самого высокого уровня встроенных функций, который вы хотели.
Это все еще может быть полезно с MSVC и ICC, чтобы вы не могли использовать наборы инструкций, которые вам не нужны.
<mmintrin.h> MMX
<xmmintrin.h> SSE
<emmintrin.h> SSE2
<pmmintrin.h> SSE3
<tmmintrin.h> SSSE3
<smmintrin.h> SSE4.1
<nmmintrin.h> SSE4.2
<ammintrin.h> SSE4A
<wmmintrin.h> AES
<immintrin.h> AVX, AVX2, FMA
Включение одного из этих подтягиваний во все предыдущие (кроме SSE4A только для AMD: immintrin.h
это не задействует)
Некоторые компиляторы также есть <zmmintrin.h>
для AVX512.
#include <x86intrin.h>
втягивать все, что вам нужно.<zmmintrin.h>
напрямую; gcc даже не предоставляет этого. Просто используйте<immintrin.h>
или еще более полный<x86intrin.h>
. Этот ответ в основном устарел, если только вы намеренно не избегаете включения встроенных функций для новых версий SSE, потому что ваш компилятор не жалуется, когда вы используете инструкцию SSE4.1 при компиляции для SSE2. (gcc / clang действительно жалуются, поэтому вы должны просто использовать для них immintrin.h. IDK о других.)В GCC / clang, если вы используете только
он будет включать все заголовки SSE / AVX, которые включены в соответствии с переключателями компилятора, например,
-march=haswell
или просто-march=native
. Кроме того, некоторые инструкции для x86, такие какbswap
илиror
становятся доступными как встроенные.Эквивалент этого заголовка в MSVC
<intrin.h>
Если вам просто нужен портативный SIMD, используйте
#include <immintrin.h>
MSVC, ICC и gcc / clang (и другие компиляторы, вроде Sun, я думаю) поддерживают этот заголовок для встроенных функций SIMD, задокументированных единственным встроенным средством поиска / поиска Intel: https://software.intel.com/sites/landingpage/IntrinsicsGuide /
источник
<x86intrin.h>
, но дает<intrin.h>
аналогичный эффект. Конечно, вам все еще нужна условная компиляция. :-(#include <immintrin.h>
. Используйте это для внутренних функций SIMD. Вам нужен только еще больший (и немного более медленный для компилятора)x86intrin.h
илиintrin.h
если вам нужны такие вещи, как встроенные функции целочисленного поворота / побитового сканирования (хотя Intel документирует некоторые из них как доступныеimmintrin.h
в своем руководстве по встроенным функциям ).x86intrin.h
/,intrin.h
но не вimmintrin.h
.Имя заголовка зависит от вашего компилятора и целевой архитектуры.
intrin.h
x86intrin.h
arm_neon.h
mmintrin.h
altivec.h
spe.h
Вы можете справиться со всеми этими случаями с помощью условных директив предварительной обработки:
источник
С этой страницы
В общем, вы можете просто включить,
immintrin.h
чтобы получить все расширения Intel, или,x86intrin.h
если хотите, все, включая_bit_scan_forward
и_rdtsc
, а также все векторные встроенные функции включают только AMD. Если вы против того, чтобы включать больше, что вам действительно нужно, вы можете выбрать правильное включение, посмотрев на таблицу.x86intrin.h
- рекомендуемый способ получить встроенные функции для AMD XOP (только Bulldozer, даже не будущие процессоры AMD) вместо того, чтобы иметь собственный заголовок.Некоторые компиляторы по-прежнему будут генерировать сообщения об ошибках, если вы используете встроенные функции для наборов инструкций, которые вы не включили (например,
_mm_fmadd_ps
без включения fma, даже если вы включаетеimmintrin.h
и включаете AVX2).источник
smmintrin
(SSE4.1) - это Penryn (45 нм Core2), а не Nehalem ("i7"). Можем ли мы перестать использовать «i7» в качестве названия архитектуры? Это бессмысленно сейчас, когда Intel продолжила использовать его для семейства SnB .immintrin.h
похоже, не включает_popcnt32
и_popcnt64
(не путать с теми, что естьpopcntintrin.h
!) встроенные функции в GCC 9.1.0. Так что, похоже, этоx86intrin.h
все еще служит цели.Поскольку многие ответов и комментарии заявили,
<x86intrin.h>
является всеобъемлющим заголовком для x86 [-64] SIMD встроенных функций . Он также предоставляет инструкции по внутренней поддержке других расширений ISA. ,, и все на этом остановились. Мне нужно было покопаться в версиях, поддерживающих заголовок, и подумал, что было бы полезно перечислить некоторые выводы ...gcc
clang
icc
gcc : поддержка
x86intrin.h
впервые появляется вgcc-4.5.0
. Этаgcc-4
серия релизов больше не поддерживается, в то времяgcc-6.x
как это текущая стабильная серия релизов.gcc-5
также представил__has_include
расширение, присутствующее во всехclang-3.x
выпусках.gcc-7
находится в предварительном выпуске (регрессионное тестирование и т. д.) и в соответствии с текущей схемой управления версиями будет выпущен какgcc-7.1.0
.clang :
x86intrin.h
похоже, поддерживался для всехclang-3.x
выпусков. Последний стабильный выпуск - этоclang (LLVM) 3.9.1
. Ветка разработки естьclang (LLVM) 5.0.0
. Непонятно, что случилось с4.x
сериалом.Apple лязгнула : досадно, что версия Apple не совпадает с версией
LLVM
проектов. Тем не менее, текущий выпуск:,clang-800.0.42.1
основан наLLVM 3.9.0
. ПерваяLLVM 3.0
базовая версия, похоже,Apple clang 2.1
вернуласьXcode 4.1
.LLVM 3.1
сначала появляется сApple clang 3.1
(числовое совпадение) вXcode 4.3.3
.Apple , также определяет ,
__apple_build_version__
например,8000042
. Похоже, это наиболее стабильная из доступных схем управления версиями строго по возрастанию. Если вы не хотите поддерживать устаревшие компиляторы, сделайте одно из этих значений минимальным требованием.clang
Следовательно, любая последняя версия , включая версии Apple, не должна иметь проблем сx86intrin.h
. Конечно, наряду с этимgcc-5
всегда можно использовать следующее:Один трюк, на который нельзя положиться, - это использование
__GNUC__
версийclang
. Версионирование по историческим причинам застряло4.2.1
. Версия, предшествующаяx86intrin.h
заголовку. Иногда это полезно, скажем, для простых расширений GNU C, которые остались обратно совместимыми.icc : насколько я могу судить,
x86intrin.h
заголовок поддерживается как минимум с Intel C ++ 16.0. Тестовая версия может быть выполнена с:#if (__INTEL_COMPILER >= 1600)
. Эта версия (и, возможно, более ранние версии) также обеспечивает поддержку__has_include
расширения.MSVC : Похоже, что
MSVC++ 12.0 (Visual Studio 2013)
это первая версия, которая предоставляетintrin.h
заголовок - нетx86intrin.h
... это предполагает:#if (_MSC_VER >= 1800)
как тест версии. Конечно, если вы пытаетесь написать код, который переносится на все эти разные компиляторы, имя заголовка на этой платформе будет наименьшей из ваших проблем.источник