2011-11-03 13 views
11

मैं कैसे परीक्षण करूं कि __m128i परिवर्तक एसएसई-2-और-पहले प्रोसेसर पर कोई nonzero मान है?एक __m128i परिवर्तनीय शून्य है?

+0

क्या आपका मतलब गैर-शून्य बिट, या 8/16/32-बिट पूर्णांक तत्व है? –

+0

@ ब्रेटहेल: मैं यह देखने के लिए परीक्षण कर रहा हूं कि वे सभी शून्य हैं या नहीं। – Mehrdad

उत्तर

11

SSE2 में आप कर सकते हैं:

__m128i zero = _mm_setzero_si128(); 
if(_mm_movemask_epi8(_mm_cmpeq_epi32(x,zero)) == 0xFFFF) 
{ 
    //the code... 
} 

इस चार पूर्णांक के परीक्षण बनाम शून्य तो प्रत्येक बाइट के लिए एक मुखौटा वापसी, इसलिए इसी int प्रत्येक के अपने बिट ऑफसेट 0 पर होगा, 4, 8 & 12, लेकिन उपर्युक्त परीक्षण पकड़ा जाएगा यदि कोई बिट सेट किया गया है, तो यदि आप मास्क को संरक्षित करते हैं तो आप सीधे अनाज वाले हिस्सों के साथ काम कर सकते हैं यदि आवश्यकता हो।

+2

+1, यह मेरी तुलना में बेहतर है। :) मैंने कभी भी movemask निर्देश का उपयोग नहीं किया है, इसलिए मुझे नहीं पता था कि आप ऐसा कर सकते हैं। एक्सडी – Mysticial

+0

+1 मैंने देखा है कि सबसे कॉम्पैक्ट समाधान, धन्यवाद! – Mehrdad

+3

अन्यथा उत्कृष्ट उत्तर में एक बग है - यदि आप सभी शून्यों की जांच कर रहे हैं, तो यह 'if (_mm_movemask_epi8 (_mm_cmpeq_epi32 (x, शून्य)) == 0xFFFF होना चाहिए। ऐसा इसलिए है क्योंकि '_mm_cmpeq_epi32' सभी 0 के लिए int सेट करता है, सभी 0 के नहीं, यदि यह शून्य के बराबर है, और फिर '_mm_movemask_epi8' पहले 16 बिट्स को तर्क में प्रत्येक बाइट के सबसे महत्वपूर्ण बिट के आधार पर सेट करता है। उम्मीद है कि लेखक उत्तर संपादित कर सकता है - मैंने कोशिश की लेकिन अस्वीकार कर दिया गया। – FarmerBob

1

पूर्णता के लिए, एसएसई 4 के साथ _mm_testz_si128 का उपयोग कर सकते हैं।

const bool isAllZero = _mm_testz_si128(a,a); 

ध्यान दें कि यह सच है जब सभी बिट्स शून्य हैं।

+1

यह वास्तव में थोड़ा तेज़ है, और इसके खिलाफ परीक्षण करने के लिए सभी शून्य पंजीकरण की आवश्यकता नहीं है। 'ptest' /' jz' 2 + 1 यूओपी है (मैक्रो-फ्यूज नहीं है)। 'पीसीएमपीक्यू '(1uop) /' pmovmsk' (1uop)/'और 0xffff' (1uop) /' cmp 0xffff/je' (1uop)। यदि आप अन्य सभी मामलों (* * * * तत्वों * के बजाय * सभी * शून्य तत्वों का परीक्षण कर रहे थे), तो वे मौजूदा इंटेल और एएमडी सीपीयू पर लगभग समान प्रदर्शन करेंगे: 'ptest' /' jnz' (3 uops) बनाम 'pcmpeq' /' pmovmsk'/'test/jnz' (3 uops)। –

+0

@ पीटरकॉर्डस, उस स्थिति में, सभी पर एक रजिस्टर सेट होने और '_mm_testc_si128' का उपयोग करने के बारे में क्या? कुछ 'कॉन्स बूल'LeastOneZero = _mm_testc_si128 (ए, allOnes)' – Antonio

+1

फिर से, 'ptest' थोड़ा तेज़ है। इसे 'ptest' के बिना करने के लिए, आप सभी वेक्टर के खिलाफ' pcmpeq 'करेंगे, और उसके बाद सभी तत्व मिलान किए गए जांचने के लिए बिल्कुल उसी अनुक्रम के साथ आगे बढ़ें। 'Pcmpeq' के साथ सभी शून्य या सभी के लिए जांच करना == किसी अन्य पैटर्न के लिए जांचने के समान है, सिवाय इसके कि स्थिरांक फ्लाई पर उत्पन्न करना आसान है (' pxor same, same' या 'pcmpeqw वही, same')। –

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