2010-12-05 9 views
5

मैं एसएसई इंट्रिनिक्स का उपयोग करके अपना कोड अनुकूलित करने की कोशिश कर रहा हूं लेकिन एक समस्या में भाग रहा हूं जहां मुझे एसईएस इंट्रिनिक्स ऑपरेशंस करने के बाद वेक्टर से पूर्णांक मान निकालने का एक अच्छा तरीका नहीं पता है। चाहते हैं।128 बिट एसएसई वेक्टर से 32 बिट पूर्णांक मानों को लोड और निकालने का सबसे प्रभावी तरीका क्या है?

क्या कोई इसे करने के लिए एक अच्छा तरीका जानता है? मैं सी में प्रोग्रामिंग कर रहा हूं और मेरा कंपाइलर जीसीसी संस्करण 4.3.2 है।

आपकी सभी मदद के लिए धन्यवाद।

+0

हम्म ... 'int * सूचक = vectoraddress; * (सूचक ++) चार गुना'? – khachik

+0

क्या कोई कारण है कि आप एसएसई रजिस्टरों में अपने सभी परिचालन नहीं कर सकते हैं और फिर जब आप पूरा कर लें तो उन्हें स्मृति में वापस डंप करें? –

+0

मैंने कोशिश की लेकिन मुझे कुछ संकलन त्रुटियां मिल रही हैं जिन्हें मैं काफी समझ नहीं पाया ... – Kaigi

उत्तर

7

यह इस बात पर निर्भर करता है कि आप अपने न्यूनतम स्तर के एसएसई समर्थन के बारे में क्या मान सकते हैं।

एसएसई 2 पर वापस जाने के लिए आपके पास _mm_extract_epi16 (PEXTRW) है जिसका उपयोग किसी 128 बिट वेक्टर से 16 बिट तत्व निकालने के लिए किया जा सकता है। 32 बिट तत्व के दो हिस्सों को प्राप्त करने के लिए आपको इसे दो बार कॉल करने की आवश्यकता होगी।

एसएसई (एसएसई 4.1 और बाद में) के हाल के संस्करणों में आपके पास _mm_extract_epi32 (PEXTRD) है जो एक निर्देश में 32 बिट तत्व निकाल सकता है।

वैकल्पिक रूप से यदि यह प्रदर्शन-महत्वपूर्ण पाश के अंदर नहीं है तो आप केवल एक यूनियन का उपयोग कर सकते हैं, उदा।

typedef union 
{ 
    __m128i v; 
    int32_t a[4]; 
} U32; 
+1

हाय पॉल, आपके उत्तर के लिए धन्यवाद। आपको उन कार्यों को कहाँ मिला (mm_extract_epi16/32)? मैं उन्हें जीसीसी दस्तावेज में नहीं देखता हूं। इसमें शामिल हैं- mmmx -msse -msse2 और -msse3 मुझे इसका उपयोग करने की प्रतीत नहीं करते हैं और संकलक कहता है कि एक निहित कार्य घोषणा है। – Kaigi

+2

@ काइगी: '_mm_extract_epi16' emmintrin.h में है,' _mm_extract_epi32' smmintrin.h में है। आपको बाद के लिए जीसीसी के एक उचित रूप से अद्यतित संस्करण की आवश्यकता होगी। –

5
_mm_extract_epi32 

निकालने intrinsics वास्तव में सबसे अच्छा विकल्प है, लेकिन यदि आप SSE2 समर्थन करने की आवश्यकता है, मैं इस सलाह देते हैं:

inline int get_x(const __m128i& vec){return _mm_cvtsi128_si32 (vec);} 
inline int get_y(const __m128i& vec){return _mm_cvtsi128_si32 (_mm_shuffle_epi32(vec,0x55));} 
inline int get_z(const __m128i& vec){return _mm_cvtsi128_si32 (_mm_shuffle_epi32(vec,0xAA));} 
inline int get_w(const __m128i& vec){return _mm_cvtsi128_si32 (_mm_shuffle_epi32(vec,0xFF));} 

मैं पाया है कि आप reinterpret_cast अगर/संघ वेक्टर किसी भी int [4] प्रतिनिधित्व के लिए संकलक चीजों को स्मृति में वापस फ्लश करने के लिए प्रेरित करता है (जो कि बुरा नहीं हो सकता है) और इसे एक int के रूप में वापस पढ़ता है, हालांकि मैंने यह देखने के लिए असेंबली को नहीं देखा है कि क्या नवीनतम संस्करण कंपाइलर्स बेहतर कोड उत्पन्न करते हैं।

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