ไฟล์ส่วนหัวใดที่ให้อินทรินนิกส์สำหรับส่วนขยายชุดคำสั่ง 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.hx86intrin.harm_neon.hmmintrin.haltivec.hspe.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 อื่น ๆ , และมีการตัดสินทั้งหมดเกี่ยวกับเรื่องนี้ ฉันจำเป็นต้องทำการขุดในเวอร์ชันที่รองรับส่วนหัวและคิดว่าอาจเป็นประโยชน์ในการแสดงรายการสิ่งที่ค้นพบ ...gccclangicc
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>ดึงทุกสิ่งที่คุณต้องการได้