2012-03-26 12 views
12

मैंने अभी एसएसई का उपयोग करना शुरू कर दिया है और मैं उलझन में हूं कि __m128i के अधिकतम पूर्णांक मान (max) को कैसे प्राप्त करें। उदाहरण के लिए:एसएसई के साथ __m128i वेक्टर में अधिकतम मूल्य प्राप्त करना?

__m128i t = _mm_setr_ps(0,1,2,3); 
// max(t) = 3; 

आसपास सर्च कर रहे हैं मुझे MAXPS अनुदेश के लिए नेतृत्व किया लेकिन मुझे लगता है कि उपयोग करने के लिए कैसे "xmmintrin.h" साथ खोजने के लिए प्रतीत नहीं कर सकते हैं।

इसके अलावा, क्या "xmmintrin.h" के लिए कोई दस्तावेज है जो आप हीडर फ़ाइल को देखने के बजाय अनुशंसा करेंगे?

+0

शफ़ल आप की जरूरत एक क्षैतिज राशि के लिए के रूप में ही, या काफी किसी अन्य क्षैतिज कमी कर रहे हैं। एसएसई 2, एसएसई 3 के साथ फ्लोट, पूर्णांक और डबल के लिए कुछ अनुकूलित संस्करणों के लिए https://stackoverflow.com/questions/6996764/fastest-way-to-do-horizontal-float-vector-sum-on-x86 देखें। AVX। इसके अलावा सीपीयू पर कौन सा शफल इष्टतम है, इसकी चर्चा भी। –

+0

यह सवाल फ्लोट बनाम पूर्णांक के बारे में उलझन में प्रतीत होता है। '__m128i' एक पूर्णांक वेक्टर है। '* _ps' और' MAXPS' पैक-सिंगल फ्लोट हैं। दस्तावेज़ों के लिए, लिंक के लिए [एसएसई टैग विकी] (https://stackoverflow.com/tags/sse/info) देखें, और https://stackoverflow.com/tags/x86/info पर कई और लिंक देखें। एक बहुत अच्छा संसाधन है [** इंटेल की आंतरिक खोज/खोजक **] (https://software.intel.com/sites/landingpage/IntrinsicsGuide/) जिसमें प्रत्येक के बारे में विवरण है, लेकिन जितना अधिक विस्तार नहीं है एएसएम निर्देश संदर्भ मैनुअल। –

उत्तर

11

आप पाते हैं अपने आप को वैक्टर पर क्षैतिज आपरेशन नहीं करना पड़ता है, खासकर अगर यह एक आंतरिक पाश अंदर है, तो यह आमतौर पर एक संकेत है कि आप अपने SIMD कार्यान्वयन के करीब पहुंच रहे हैं तो गलत रास्ता। सिमड वैक्टरों पर तत्व-वार संचालित करना पसंद करता है - यदि आप क्षैतिज रूप से नहीं, तो "लंबवत"।

प्रलेखन के लिए, very useful reference on intel.com है जिसमें एसएमई के विभिन्न स्वादों के माध्यम से एमएमएक्स से सभी एवीएक्स और एवीएक्स -512 तक सभी ऑपकोड और इंट्रिनिक्स शामिल हैं।

+0

लिंक के लिए धन्यवाद। क्षैतिज भाग केवल लूप स्थिति के लिए है, लेकिन मैं अपने दृष्टिकोण को संशोधित कर दूंगा – Shane

+0

लिंक वर्तमान में है: https://software.intel.com/sites/landingpage/IntrinsicsGuide/ –

+0

@MarkLakata: धन्यवाद - उत्तर अपडेट किया गया - मुझे पुरानी याद आती है ऑफ़लाइन गाइड - साथ ही साथ इंटरनेट कनेक्शन के बिना काम करना भी उपयोगी था कि आप अन्य उपयोगों के लिए डेटा को स्क्रैप कर सकते हैं। हालांकि कभी भी ध्यान न दें - नया ऑनलाइन संस्करण अभी भी अच्छा है। –

4

एसएसई में कोई क्षैतिज अधिकतम ऑपोड नहीं है (कम से कम उस बिंदु तक जहां मैंने नए एसएसई निर्देशों का ट्रैक रखा है)।

तो आप कुछ शफल कर रहे हैं। आप क्या अंत है साथ ...

movhlps %xmm0, %xmm1   # Move top two floats to lower part of %xmm1 
maxps %xmm1, %xmm0   # Get minimum of sets of two floats 
pshufd $0x55, %xmm0, %xmm1  # Move second float to lower part of %xmm1 
maxps %xmm1, %xmm0   # Get minimum of all four floats originally in %xmm0 

http://locklessinc.com/articles/instruction_wishlist/

MSDN आंतरिक और स्थूल समारोह मैपिंग प्रलेखित

http://msdn.microsoft.com/en-us/library/t467de55.aspx

8

this page के अनुसार है, वहाँ कोई क्षैतिज अधिकतम है, और आपको लंबवत तत्वों का परीक्षण करने की आवश्यकता है:

movhlps xmm1,xmm0   ; Move top two floats to lower part of xmm1 
maxps xmm0,xmm1   ; Get maximum of the two sets of floats 
pshufd xmm1,xmm0,$55  ; Move second float to lower part of xmm1 
maxps xmm0,xmm1   ; Get minimum of the two remaining floats 

इसके विपरीत, कम से कम हो रही है:

movhlps xmm1,xmm0 
minps xmm0,xmm1 
pshufd xmm1,xmm0,$55 
minps xmm0,xmm1 
+1

'maxps' निर्देशों के बीच 'pshufd' में कई CPUs (इंटेल समेत) पर अतिरिक्त विलंबता है। एसएसई 3 'movshdup' रजिस्टर के प्रत्येक छमाही में ऊपरी फ्लोट को डुप्लिकेट करेगा, ताकि आप इसे movaps प्रति से बचने के लिए उपयोग कर सकें। –

+0

@ पीटरकॉर्डस, क्या आप अपना खुद का अनुकूलित समाधान लिख सकते हैं? अगर यह फ्लोट का वेक्टर था तो क्या यह अलग होगा? धन्यवाद। – Royi

+0

@ रॉय: यह उत्तर * 'फ्लोट 'के वेक्टर के लिए है (क्योंकि प्रश्न गलत शीर्षक वाला है या फ्लोट बनाम पूर्णांक के बारे में मिश्रित है, प्रश्न पर मेरी टिप्पणियां देखें)। किसके लिए माइक्रोआर्किटेक्चर अनुकूलित किया गया है, और एसएसई के किस स्तर के साथ? SSE3? या एसएसई 2 तक सीमित है? या AVX2? विभिन्न अनुकूलित फ्लोट और पूर्णांक शफल के लिए https://stackoverflow.com/questions/6996764/fastest-way-to-do-horizontal-float-vector-sum-on-x86 (लेकिन 'अधिकतम' के साथ' add' को प्रतिस्थापित करें) देखें । –

14

यदि कोई परवाह करता है और आंतरिक रूप से इन दिनों जाने का तरीका प्रतीत होता है, तो यहां अंतर्निहितता के मामले में एक समाधान है।

int horizontal_max_Vec4i(__m128i x) { 
    __m128i max1 = _mm_shuffle_epi32(x, _MM_SHUFFLE(0,0,3,2)); 
    __m128i max2 = _mm_max_epi32(x,max1); 
    __m128i max3 = _mm_shuffle_epi32(max2, _MM_SHUFFLE(0,0,0,1)); 
    __m128i max4 = _mm_max_epi32(max2,max3); 
    return _mm_cvtsi128_si32(max4); 
} 

मुझे लगता है कि अगर इस से किसी भी बेहतर नहीं जानता:

int horizontal_max_Vec4i(__m128i x) { 
    int result[4] __attribute__((aligned(16))) = {0}; 
    _mm_store_si128((__m128i *) result, x); 
    return max(max(max(result[0], result[1]), result[2]), result[3]); 
} 
+1

बेशक, यह बेहतर है। – user1095108

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