कौन सी हेडर फाइलें विभिन्न x86 SIMD अनुदेश सेट एक्सटेंशन (MMX, SSE, AVX, ...) के लिए आंतरिक प्रदान करती हैं? ऐसी सूची ऑनलाइन खोजना असंभव है। यदि मैं गलत हूं तो मुझे सही करों।
कौन सी हेडर फाइलें विभिन्न x86 SIMD अनुदेश सेट एक्सटेंशन (MMX, SSE, AVX, ...) के लिए आंतरिक प्रदान करती हैं? ऐसी सूची ऑनलाइन खोजना असंभव है। यदि मैं गलत हूं तो मुझे सही करों।
जवाबों:
इन दिनों आपको सामान्य रूप से सिर्फ शामिल करना चाहिए <immintrin.h>
। इसमें सब कुछ शामिल है।
जीसीसी और बजना 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
पिछले सभी में इन पुलों में से एक को शामिल करना (केवल AMDE SSA4A को छोड़कर: जो immintrin.h
इसमें नहीं खींचता)
कुछ संकलक भी <zmmintrin.h>
AVX512 के लिए हैं।
<zmmintrin.h>
सीधे शामिल न करें ; जीसीसी भी प्रदान नहीं करता है। बस का उपयोग करें<immintrin.h>
या यहां तक कि अधिक-पूर्ण <x86intrin.h>
। यह उत्तर मूल रूप से अप्रचलित है, जब तक कि आप जानबूझकर एसएसई के नए संस्करणों के लिए इंट्रेंसिक्स सहित से परहेज नहीं कर रहे हैं क्योंकि आपका कंपाइलर SSE2 के लिए संकलन करते समय SSE4.1 निर्देश का उपयोग करने पर शिकायत नहीं करता है। (जीसीसी / बजना करते शिकायत करते हैं, तो आप सिर्फ उनके लिए immintrin.h का उपयोग करना चाहिए दूसरों के बारे में IDK।।)
जीसीसी / क्लैंग पर, यदि आप सिर्फ उपयोग करते हैं
#include <x86intrin.h>
इसमें सभी SSE / AVX हेडर शामिल होंगे जो कंपाइलर स्विच के अनुसार -march=haswell
या जैसे ही सक्षम होते हैं -march=native
। इसके अतिरिक्त कुछ x86 विशिष्ट निर्देश जैसे bswap
या ror
आंतरिक रूप में उपलब्ध हो जाते हैं।
इस हेडर के बराबर MSVC <intrin.h>
यदि आप केवल पोर्टेबल SIMD चाहते हैं, तो उपयोग करें #include <immintrin.h>
MSVC, ICC, और gcc / clang (और Sun जैसे अन्य कंपाइलर) मुझे लगता है कि इंटेल के एकमात्र आंतरिक खोजक / खोज टूल द्वारा प्रलेखित SIMD आंतरिक के लिए सभी इस हेडर का समर्थन करते हैं: https : //software.intel.sites/landingpage/IntrinsicsGuide /
<x86intrin.h>
, लेकिन <intrin.h>
एक समान प्रभाव प्राप्त करता है। आपको अभी भी सशर्त संकलन की आवश्यकता है। :-(
#include <immintrin.h>
। कि SIMD आंतरिक के लिए उपयोग करें। आपको केवल सम-बड़ा (और संकलक के लिए थोड़ा धीमा) की आवश्यकता है x86intrin.h
या intrin.h
यदि आपको पूर्णांक घुमाव / बिट-स्कैन इंट्रिंसिक्स जैसे सामान की आवश्यकता है (हालांकि इंटेल उन लोगों में से कुछ के रूप में उपलब्ध है 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
सभी इंटेल एक्सटेंशन प्राप्त करने के लिए शामिल कर सकते हैं , या x86intrin.h
यदि आप सब कुछ चाहते हैं, जिसमें शामिल हैं _bit_scan_forward
और _rdtsc
साथ ही सभी वेक्टर आंतरिक भी एएमडी-केवल शामिल हैं। यदि आप अधिक शामिल हैं, जिसकी आपको वास्तव में आवश्यकता है, तो आप तालिका को देखकर सही शामिल कर सकते हैं।
x86intrin.h
एएमडी एक्सओपी (बुलडोजर-केवल, यहां तक कि एएमडी सीपीयू भी नहीं) के लिए आंतरिक रूप से प्राप्त करने के लिए अनुशंसित तरीका है , बजाय इसके हेडर होने के।
कुछ कंपाइलर अभी भी त्रुटि संदेश उत्पन्न करेंगे यदि आप निर्देश-सेट के लिए आंतरिक का उपयोग करते हैं जो आपने सक्षम नहीं किया है (उदाहरण _mm_fmadd_ps
के लिए fma को सक्षम किए बिना, भले ही आप शामिल हों immintrin.h
और AVX2 को सक्षम करें)।
smmintrin
(SSE4.1) पेन्री (45nm Core2) है, नेहेल्म ("i7") नहीं। क्या हम वास्तुकला के नाम के रूप में "i7" का उपयोग बंद कर सकते हैं? अब यह अर्थहीन है कि इंटेल ने इसे SnB- परिवार के लिए उपयोग किया है ।
immintrin.h
जीसीसी 9.1.0 पर इंट्रिंसिक्स में शामिल करने _popcnt32
और _popcnt64
(उन लोगों के साथ भ्रमित नहीं होने के लिए) प्रकट नहीं होता है popcntintrin.h
। तो यह प्रतीत होता है x86intrin.h
अभी भी एक उद्देश्य में कार्य करता है।
के रूप में जवाब और टिप्पणियों के कई कहा है, <x86intrin.h>
है 86 [-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 भी __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)
संस्करण परीक्षण के रूप में। बेशक, अगर आप इन सभी अलग-अलग संकलकों में पोर्टेबल है कोड लिखने की कोशिश कर रहे हैं, तो इस प्लेटफ़ॉर्म पर हेडर नाम आपकी समस्याओं का कम से कम होगा।
#include <x86intrin.h>
जो आपकी जरूरत की हर चीज में खींचता है।