ไฟล์ส่วนหัวใดที่ให้อินทรินนิกส์สำหรับส่วนขยายชุดคำสั่ง x86 SIMD (MMX, SSE, AVX, ... ) ดูเหมือนว่าจะไม่พบรายการดังกล่าวทางออนไลน์ ช่วยแก้ให้ด้วยนะถ้าฉันผิด.
ไฟล์ส่วนหัวใดที่ให้อินทรินนิกส์สำหรับส่วนขยายชุดคำสั่ง x86 SIMD (MMX, SSE, AVX, ... ) ดูเหมือนว่าจะไม่พบรายการดังกล่าวทางออนไลน์ ช่วยแก้ให้ด้วยนะถ้าฉันผิด.
คำตอบ:
วันนี้คุณควรรวม<immintrin.h>
ไว้ มันรวมทุกอย่าง
GCC และเสียงดังกราวจะหยุดคุณจากการใช้ intrinsics สำหรับคำแนะนำคุณยังไม่ได้เปิดใช้งานที่รวบรวมเวลา (เช่นกับ-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
<zmmintrin.h>
โดยตรง gcc ไม่ได้ให้ไว้ เพียงแค่ใช้<immintrin.h>
หรือยิ่ง - สมบูรณ์<x86intrin.h>
มากขึ้น คำตอบนี้เป็นคำตอบที่ล้าสมัยโดยทั่วไปเว้นแต่คุณจะจงใจหลีกเลี่ยงการรวมอินทรินนิกสำหรับ SSE เวอร์ชันใหม่เนื่องจากคอมไพเลอร์ของคุณไม่บ่นเมื่อคุณใช้คำสั่ง SSE4.1 ในขณะที่รวบรวม SSE2 (GCC / เสียงดังกราวไม่บ่นดังนั้นคุณก็ควรใช้ immintrin.h สำหรับพวกเขา IDK เกี่ยวกับคนอื่น..)
ใน GCC / clang ถ้าคุณใช้เพียง
#include <x86intrin.h>
มันจะรวมส่วนหัวของ SSE / AVX ทั้งหมดซึ่งมีการใช้งานตามที่สวิทช์คอมไพเลอร์เหมือนหรือเพียงแค่-march=haswell
-march=native
นอกจากนี้คำแนะนำเฉพาะบางอย่างของ x86 เช่นbswap
หรือror
พร้อมใช้งานในรูปแบบที่แท้จริง
เทียบเท่า MSVC ของส่วนหัวนี้ <intrin.h>
หากคุณต้องการเพียง SIMD แบบพกพาให้ใช้ #include <immintrin.h>
MSVC, ICC และ gcc / clang (และคอมไพเลอร์อื่น ๆ เช่น Sun I think) ทั้งหมดรองรับส่วนหัวนี้สำหรับ SIMD intrinsics ที่จัดทำเอกสารโดยเครื่องมือค้นหา / เครื่องมือค้นหาภายในของ Intel: https://software.intel.com/sites/landingpage/IntrinsicsGuide /
<x86intrin.h>
แต่<intrin.h>
ให้ผลลัพธ์ที่คล้ายกัน คุณยังคงต้องมีการรวบรวมตามเงื่อนไขแน่นอน :-(
#include <immintrin.h>
ที่สำคัญมี ใช้สำหรับ SIMD intrinsics คุณต้องการเพียงแค่คอมไพเลอร์ที่ใหญ่กว่าเท่านั้น (และช้ากว่าเล็กน้อยสำหรับคอมไพเลอร์) 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
คุณสามารถจัดการกรณีเหล่านี้ทั้งหมดด้วยคำสั่งก่อนการประมวลผลแบบมีเงื่อนไข:
#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
จากหน้านี้
+----------------+------------------------------------------------------------------------------------------+
| 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
เพื่อรับส่วนขยายของ 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 (45nm Core2) ไม่ใช่ Nehalem ("i7") เราสามารถหยุดใช้ "i7" เป็นชื่อสถาปัตยกรรมได้หรือไม่? ตอนนี้ Intel ยังคงใช้มันสำหรับ SnB-familyอย่างไร้ความหมาย
immintrin.h
ดูเหมือนจะไม่รวม_popcnt32
และ_popcnt64
(เพื่อไม่ให้สับสนกับสิ่งที่อยู่ในpopcntintrin.h
!) ใน GCC 9.1.0 ดังนั้นดูเหมือนว่าx86intrin.h
ยังคงตอบสนองวัตถุประสงค์
เป็นจำนวนมากของคำตอบและแสดงความคิดเห็นได้กล่าว<x86intrin.h>
คือส่วนหัวที่ครอบคลุมสำหรับ x86 [-64] SIMD intrinsics นอกจากนี้ยังมีคำแนะนำที่สนับสนุนภายในสำหรับส่วนขยาย 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
และต่อไปนี้โครงการเวอร์ชันปัจจุบันจะได้รับการปล่อยตัวออกมาเป็น
เสียงดัง : 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_build_version__
8000042
ดูเหมือนว่าจะเกี่ยวกับรูปแบบการกำหนดเวอร์ชันจากน้อยไปหามากที่เสถียรที่สุด หากคุณไม่ต้องการสนับสนุนคอมไพเลอร์แบบเดิมให้กำหนดค่าเหล่านี้ให้เป็นข้อกำหนดขั้นต่ำ
รุ่นใด ๆ ที่ผ่านมาของการรวมถึงรุ่นที่แอปเปิ้ลจึงไม่ควรมีปัญหากับclang
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)
เป็นการทดสอบเวอร์ชัน แน่นอนว่าหากคุณกำลังพยายามเขียนโค้ดที่พกพาได้ในคอมไพเลอร์ต่างๆเหล่านี้ชื่อส่วนหัวบนแพลตฟอร์มนี้จะเป็นปัญหาน้อยที่สุด
#include <x86intrin.h>
ดึงทุกสิ่งที่คุณต้องการได้