x86 SIMD 내장 함수의 헤더 파일


131

어떤 x86 SIMD 명령어 세트 확장 (MMX, SSE, AVX, ...)에 내장 함수를 제공하는 헤더 파일은 무엇입니까? 온라인에서 그러한 목록을 찾는 것은 불가능합니다. 틀 렸으면 말해줘.

답변:


174

요즘에는 일반적으로 포함해야합니다 <immintrin.h>. 모든 것을 포함합니다.

GCC와 그 소리는 지침이 컴파일시에 설정하지 않은 내장 함수를 사용을 중지합니다 (예 :와 -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

이전의 모든 것들에 이러한 immintrin.h풀 중 하나를 포함 (AMD 전용 SSE4A를 제외하고 는 :)

일부 컴파일러에는 <zmmintrin.h>AVX512 도 있습니다 .


62
또는 #include <x86intrin.h>필요한 것을 모두 가져올 수 있습니다 .
Paul R

2
zmmintrin.h에는 AVX-512 내장 함수가 있습니다.
onitake

3
SSE3 / SSSE3 / SSE4.1 및 4.2에서 p, t, s 및 n이 왜됩니까? 그 캐릭터들은 무엇을 상징합니까?
phuclv

5
@ LưuVĩnhPhúc SSE3 = Prescott 새로운 명령어, SSSE3 = Tejas 새로운 명령어. SSE4.2와 AES는 그들이 도입 한 프로세서 제품군 (네 할렘과 웨스트 미어)을 참조한다고 생각합니다.
Drew McGowen

14
<zmmintrin.h>직접 포함하지 마십시오 . gcc는 그것을 제공하지도 않습니다. 그냥 사용<immintrin.h> 또는 짝수 더 완성 <x86intrin.h>. SSE2에 대해 컴파일하는 동안 SSE4.1 명령어를 사용할 때 컴파일러가 불평하지 않기 때문에 최신 버전의 SSE에 내장 함수를 의도적으로 포함하지 않는 한이 대답은 기본적으로 사용되지 않습니다. (gcc / clang 불평하므로, 그들에게 immintrin.h를 사용해야합니다. 다른 사람들에 대한 IDK.)
Peter Cordes

76

GCC / clang에서

#include <x86intrin.h>

여기에는 컴파일러 스위치에 따라 -march=haswell또는 처럼 활성화 된 모든 SSE / AVX 헤더가 포함됩니다 -march=native. 또한 일부 x86 특정 명령어 는 내장 함수 와 같 bswap거나 ror내장 함수로 제공됩니다.


이 헤더에 해당하는 MSVC <intrin.h>


휴대용 SIMD 만 원한다면 #include <immintrin.h>

MSVC, ICC 및 gcc / clang (및 Sun과 같은 다른 컴파일러)은 모두 Intel의 유일한 내장 검색기 / 검색 도구에 의해 문서화 된 SIMD 내장 함수에 대해이 헤더를 지원합니다. https://software.intel.com/sites/landingpage/IntrinsicsGuide /


새로운 버전이 있을지 모르겠다 ... 어쨌든 gcc, icc 및 clang이 가지고있는 한, 사용하는 것이 좋다 :-)
Gunther Piez

5
MSVC에는가 <x86intrin.h>없지만 <intrin.h>비슷한 효과를 얻습니다. 물론 여전히 조건부 컴파일이 필요합니다. :-(
코디 그레이

모든 주요 x86 컴파일러에는 #include <immintrin.h>. SIMD 내장 함수에 사용하십시오. 인텔은 더 크 x86intrin.h거나 ( 컴파일러보다 약간 느리게) intrin.h필요 하거나 정수 회전 / 비트 스캔 내장 함수와 같은 항목이 필요한 경우 (Intel immintrin.h 은 내장 안내서에서 사용 가능한 일부 문서를 작성하지만 ) 필요합니다.
Peter Cordes

IIRC, 일부 비 SIMD의 내장 함수 immintrin.h에있는 것으로 인텔 문서,하지만 GCC, 그 소리, 및 / 또는 MSVC 만에이있다 x86intrin.h/ intrin.h하지만 하지 의를 immintrin.h.
Peter Cordes

56

헤더 이름은 컴파일러와 대상 아키텍처에 따라 다릅니다.

  • Windows 용 Microsoft C ++ (타겟팅 x86, x86-64 또는 ARM) 및 Intel C / C ++ 컴파일러 intrin.h
  • x86 / x86-64를 타겟팅하는 gcc / clang / icc의 경우 x86intrin.h
  • NEON을 사용하여 ARM을 대상으로하는 gcc / clang / armcc의 경우 arm_neon.h
  • WMMX를 사용하여 ARM을 대상으로하는 gcc / clang / armcc의 경우 mmintrin.h
  • VMX (일명 Altivec) 및 / 또는 VSX를 사용하는 PowerPC를 대상으로하는 gcc / clang / xlcc의 경우 altivec.h
  • SPE를 사용하는 PowerPC를 대상으로하는 gcc / clang의 경우 spe.h

조건부 전처리 지시문을 사용하여 이러한 모든 경우를 처리 할 수 ​​있습니다.

#if defined(_MSC_VER)
     /* Microsoft C/C++-compatible compiler */
     #include <intrin.h>
#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
     /* GCC-compatible compiler, targeting x86/x86-64 */
     #include <x86intrin.h>
#elif defined(__GNUC__) && defined(__ARM_NEON__)
     /* GCC-compatible compiler, targeting ARM with NEON */
     #include <arm_neon.h>
#elif defined(__GNUC__) && defined(__IWMMXT__)
     /* GCC-compatible compiler, targeting ARM with WMMX */
     #include <mmintrin.h>
#elif (defined(__GNUC__) || defined(__xlC__)) && (defined(__VEC__) || defined(__ALTIVEC__))
     /* XLC or GCC-compatible compiler, targeting PowerPC with VMX/VSX */
     #include <altivec.h>
#elif defined(__GNUC__) && defined(__SPE__)
     /* GCC-compatible compiler, targeting PowerPC with SPE */
     #include <spe.h>
#endif

다음은 목록에 추가 할 내용입니다. gcc를 사용하는 UltraSPARC + VIS에는 visintrin.h를 사용하십시오. Sun의 VSDK를 사용하는 경우 vis.h는 다른 내장 함수를 제공합니다. 문서는 여기에서 찾을 수 있습니다. GCC VIS builtins , Sun VIS 사용자 안내서 .
onitake

44

페이지에서

+----------------+------------------------------------------------------------------------------------------+
|     Header     |                                         Purpose                                          |
+----------------+------------------------------------------------------------------------------------------+
| x86intrin.h    | Everything, including non-vector x86 instructions like _rdtsc().                         |
| mmintrin.h     | MMX (Pentium MMX!)                                                                       |
| mm3dnow.h      | 3dnow! (K6-2) (deprecated)                                                               |
| xmmintrin.h    | SSE + MMX (Pentium 3, Athlon XP)                                                         |
| emmintrin.h    | SSE2 + SSE + MMX (Pentium 4, Athlon 64)                                                  |
| pmmintrin.h    | SSE3 + SSE2 + SSE + MMX (Pentium 4 Prescott, Athlon 64 San Diego)                        |
| tmmintrin.h    | SSSE3 + SSE3 + SSE2 + SSE + MMX (Core 2, Bulldozer)                                      |
| popcntintrin.h | POPCNT (Nehalem (Core i7), Phenom)                                                       |
| ammintrin.h    | SSE4A + SSE3 + SSE2 + SSE + MMX (AMD-only, starting with Phenom)                         |
| smmintrin.h    | SSE4_1 + SSSE3 + SSE3 + SSE2 + SSE + MMX (Penryn, Bulldozer)                             |
| nmmintrin.h    | SSE4_2 + SSE4_1 + SSSE3 + SSE3 + SSE2 + SSE + MMX (Nehalem (aka Core i7), Bulldozer)     |
| wmmintrin.h    | AES (Core i7 Westmere, Bulldozer)                                                        |
| immintrin.h    | AVX, AVX2, AVX512, all SSE+MMX (except SSE4A and XOP), popcnt, BMI/BMI2, FMA             |
+----------------+------------------------------------------------------------------------------------------+

그래서 일반적으로 당신 만 포함 할 수 있습니다 immintrin.h모든 인텔 확장을 얻기 위해, 또는 x86intrin.h당신은 모든 것을 포함하려는 경우 _bit_scan_forward_rdtsc,뿐만 아니라 모든 벡터 내장 함수를 AMD-유일한 사람을 포함한다. 실제로 필요한 것 이상을 포함하지 않으면 테이블을보고 올바른 포함을 선택할 수 있습니다.

x86intrin.h는 자체 헤더를 사용하지 않고 AMD XOP (Bulldozer 전용, 향후 AMD CPU는 아님)에 대한 내장 기능을 얻는 권장 방법 입니다.

활성화하지 않은 명령어 세트에 내장 함수를 사용하는 경우 일부 컴파일러는 여전히 오류 메시지를 생성합니다 (예 : AVX2 _mm_fmadd_ps를 포함 immintrin.h하고 활성화 하더라도 fma를 활성화하지 않음 ).


1
smmintrin(SSE4.1)은 Nehalem ( "i7")이 아닌 Penryn (45nm Core2)입니다. "i7"을 아키텍처 이름으로 사용하는 것을 중단 할 수 있습니까? 인텔이 SnB 제품군에 계속 사용한다는 것은 의미가 없습니다 .
Peter Cordes 2016 년

immintrin.h포함 나타나지 않습니다 _popcnt32_popcnt64(의 번호와 혼동하지 popcntintrin.hGCC 9.1.0에!) 내장 함수. 그래서 그것은 x86intrin.h여전히 목적을 제공하는 것으로 보입니다 .
Thom Wiggers

12

답변 및 의견의 대부분이 언급했듯이 <x86intrin.h>이다 86 [-64] SIMD의 내장 함수에 대한 포괄적 인 헤더. 또한 다른 ISA 확장에 대한 지침을 지원하는 내장 함수도 제공합니다. , 그리고 이것 에 모두 정했습니다. 헤더를 지원하는 버전을 파헤쳐 야했고 결과를 나열하는 것이 도움이 될 것이라고 생각했습니다 ...gccclangicc

  • gcc :에 대한 지원이에 x86intrin.h나타납니다 gcc-4.5.0. gcc-4릴리즈 시리즈는 더 이상 동안 유지되고 있지 gcc-6.x는 IS 현재 안정적인 릴리스 시리즈. 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 clang : 성가신 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_build_version__, 예 8000042. 이것은 가장 안정적이고 엄격하게 상승하는 버전 관리 체계에 관한 것 같습니다. 레거시 컴파일러를 지원하지 않으려면이 값 중 하나를 최소 요구 사항으로 설정하십시오.

clang따라서 Apple 버전을 포함한 최신 버전은 에 문제가 없어야 x86intrin.h합니다. 물론와 함께 gcc-5항상 다음을 사용할 수 있습니다.

#if defined (__has_include) && (__has_include(<x86intrin.h>))
#include <x86intrin.h>
#else
#error "upgrade your compiler. it's free..."
#endif

실제로 신뢰할 수없는 트릭은의 __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)버전 테스트로. 물론, 다른 모든 컴파일러에서 이식 가능한 코드를 작성하려는 경우이 플랫폼의 헤더 이름이 가장 문제가되지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.