2013-03-23 6 views
13

मैं एक उदाहरण देकर अपने प्रश्न पूछूंगा। अब मेरे पास do_something() नामक एक फ़ंक्शन है।जीसीसी में एसएसई इंट्रिनिक्स के विभिन्न संस्करणों का उपयोग करने का सही तरीका क्या है?

इसमें तीन संस्करण हैं: do_something(), do_something_sse3(), और do_something_sse4()। जब मेरा प्रोग्राम चलता है, तो यह सीपीयू फीचर का पता लगाएगा (देखें कि यह एसएसई 3 या एसएसई 4 का समर्थन करता है) और तदनुसार तीन संस्करणों में से एक को कॉल करें।

समस्या है: जब मैं जीसीसी के साथ अपने कार्यक्रम बनाने, मैं संकलित करने के लिए (उदाहरण के लिए हेडर फाइल <smmintrin.h> के लिए शामिल किया जाना है) do_something_sse4() के लिए -msse4 सेट करना होगा।

हालांकि, अगर मैं -msse4 सेट करता हूं, तो जीसीसी को एसएसई 4 निर्देशों का उपयोग करने की अनुमति है, और कुछ अंतर्निहित do_something_sse3() में कुछ एसएसई 4 निर्देशों में भी अनुवाद किया जाता है। तो यदि मेरा प्रोग्राम सीपीयू पर चलता है जिसमें केवल एसएसई 3 (लेकिन कोई एसएसई 4) समर्थन नहीं है, तो do_something_sse3() पर कॉल करते समय यह "अवैध निर्देश" का कारण बनता है।

शायद मेरे पास कुछ खराब अभ्यास है। क्या आप कुछ सुझाव दे सकते हैं? धन्यवाद।

+5

मुझे लगता है कि मानक दृष्टिकोण विभिन्न संकलन इकाइयों में विभिन्न संस्करणों को संकलित करना है। – Mysticial

+0

@ मिस्टिकियल, पहले मेरे प्रश्न को संपादित करने के लिए धन्यवाद। जैसा कि मैं समझता हूं, "अलग-अलग संकलन इकाइयों में विभिन्न संस्करणों को संकलित करें" का अर्थ है: सभी 'do_things_sse4' फ़ाइल' functios_sse4.c' में रखें, और इसे '-msse4' विकल्प के साथ संकलित करें; और 'functions_sse3.c' को' -msse3' के साथ संकलित करें। मैं कोशिश करूँगा (मुझे अपने कोडों का पुनर्निर्माण करने की आवश्यकता हो सकती है, जिन्हें मूल रूप से एमएसवीसी के लिए लिखा गया था) – shengbinmeng

+0

हां, यही वही है जो मेरा मतलब था। :) – Mysticial

उत्तर

9

मुझे लगता है कि मिस्टिकल के टिप ठीक है, लेकिन यदि आप वास्तव में एक फ़ाइल में क्या करना चाहते हैं, तो आप उचित pragmas उपयोग कर सकते हैं, उदाहरण के लिए:

#pragma GCC target("sse4.1") 

जीसीसी 4.4 की जरूरत है, AFAIR । http://notabs.org/lfsr/software/index.htm

लेकिन जब जीसीसी लिंक समय अनुकूलन (-flto) प्रयोग किया जाता है यहाँ तक कि इस विधि में विफल रहता है:

+0

इस सुझाव के लिए धन्यवाद। मैं बाद में '# प्रगमा 'निर्देश भी आज़माउंगा। – shengbinmeng

+0

#pragma जीसीसी लक्ष्य ("एसएसई 4") के साथ भी smmintrin.h शामिल नहीं कर सकता – Trass3r

0

यहाँ प्रत्येक अनुकूलन सेटिंग के लिए एक अलग वस्तु फ़ाइल संकलन का एक उदाहरण है। तो विभिन्न प्रोसेसर के लिए पूर्ण अनुकूलन के साथ एक निष्पादन योग्य कैसे बनाया जा सकता है? एकमात्र समाधान जो मैं पा सकता हूं उसका उपयोग करना सी फाइलों को एक संकलन इकाई के रूप में व्यवहार करने के निर्देशों को शामिल करना है ताकि -फ्लो की आवश्यकता न हो। http://notabs.org/blcutil/index.htm

2

मुझे लगता है कि आप का निर्माण करने के लिए क्या एक "सीपीयू डिस्पैचर" कहा जाता है चाहता हूँ: यहाँ है कि विधि का उपयोग कर एक उदाहरण है। मुझे जीसीसी के लिए एक काम (जहां तक ​​मुझे पता है) मिला है लेकिन इसे विजुअल स्टूडियो के साथ काम करने के लिए नहीं मिला है।
cpu dispatcher for visual studio for AVX and SSE

मैं Agner कोहरा के vectorclass और फ़ाइल dispatch_example.cpp की जाँच होगी http://www.agner.org/optimize/#vectorclass

g++ -O3 -msse2 -c dispatch_example.cpp -od2.o 
g++ -O3 -msse4.1 -c dispatch_example.cpp -od5.o 
g++ -O3 -mavx -c dispatch_example.cpp -od8.o 
g++ -O3 -msse2  instrset_detect.cpp d2.o d5.o d8.o 
0

आप एक i686 या x86_64 मशीन पर जीसीसी 4.9 या इसके बाद के संस्करण का उपयोग कर रहे हैं, तो आप होने की अपेक्षा की जाती है अपने -march=XXX और -mXXX विकल्पों के बावजूद intrinsics का उपयोग करने में सक्षम। आप अपने do_something() तदनुसार लिख सकते हैं:

void do_something() 
{ 
    byte temp[18]; 

    if (HasSSE2()) 
    { 
     const __m128i i = _mm_loadu_si128((const __m128i*)(ptr)); 
     ... 
    } 
    else if (HasSSSE3()) 
    { 
     const __m128i MASK = _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3); 
     _mm_storeu_si128(reinterpret_cast<__m128i*>(temp), 
      _mm_shuffle_epi8(_mm_loadu_si128((const __m128i*)(ptr)), MASK)); 
    } 
    else 
    { 
     // Do the byte swap/endian reversal manually 
     ... 
    } 
} 

आप HasSSE2(), HasSSSE3() और दोस्तों की आपूर्ति करने के लिए है। Intrinsics for CPUID like informations? भी देखें।

भी GCC Issue 57202 - Please make the intrinsics headers like immintrin.h be usable without compiler flags देखें। लेकिन मुझे विश्वास नहीं है कि सुविधा काम करती है। मैं नियमित रूप से संकलन विफलताओं का सामना करता हूं क्योंकि जीसीसी इंट्रिनिक्स उपलब्ध नहीं कराती है।

संबंधित मुद्दे