2010-10-19 22 views
5

मैं एसएसई के लिए बहुत नया हूं और इंट्रिनिक्स का उपयोग कर कोड के एक अनुभाग को अनुकूलित किया है। मैं ऑपरेशन से खुद खुश हूं, लेकिन मैं परिणाम लिखने का एक बेहतर तरीका ढूंढ रहा हूं। परिणाम तीन _m128i चर में समाप्त होते हैं।एसएसई इंट्रिनिक्स के साथ गैर-संगत मेमोरी लोकेशन में मूल्यों को कैसे स्टोर करें?

जो मैं करने की कोशिश कर रहा हूं वह परिणाम मानों से विशिष्ट बाइट्स को गैर-संगत स्मृति स्थानों तक स्टोर करता है। मैं वर्तमान में इस कर रहा हूँ:

__m128i values0,values1,values2; 

/*Do stuff and store the results in values0, values1, and values2*/ 

y[0]  = (BYTE)_mm_extract_epi16(values0,0); 
cb[2]=cb[3] = (BYTE)_mm_extract_epi16(values0,2); 
y[3]  = (BYTE)_mm_extract_epi16(values0,4); 
cr[4]=cr[5] = (BYTE)_mm_extract_epi16(values0,6); 

cb[0]=cb[1] = (BYTE)_mm_extract_epi16(values1,0); 
y[1]  = (BYTE)_mm_extract_epi16(values1,2); 
cr[2]=cr[3] = (BYTE)_mm_extract_epi16(values1,4); 
y[4]  = (BYTE)_mm_extract_epi16(values1,6); 

cr[0]=cr[1] = (BYTE)_mm_extract_epi16(values2,0); 
y[2]  = (BYTE)_mm_extract_epi16(values2,2); 
cb[4]=cb[5] = (BYTE)_mm_extract_epi16(values2,4); 
y[5]  = (BYTE)_mm_extract_epi16(values2,6); 

y, cb, और cr कहाँ बाइट (unsigned char) सरणियों कर रहे हैं। यह उन कारणों से गलत लगता है जिन्हें मैं परिभाषित नहीं कर सकता। क्या किसी के पास बेहतर तरीके से कोई सुझाव है?

धन्यवाद!

+0

मुझे लगता है कि आप _mm_packXxx इंट्रिनिक्स में से एक के लिए देख रहे हैं। –

+0

मैंने उन पर ध्यान दिया, लेकिन उनमें से कोई भी ऐसा नहीं कर रहा था जो मैं चाहता हूं। मैं फिर से जांच जाऊंगा, धन्यवाद। – Scott

उत्तर

9

आप मूल रूप से नहीं कर सकते - एसएसई में स्कैटर स्टोर नहीं है, और यह सभी तरह के संगत डेटा धाराओं पर वेक्टरकृत काम करने के विचार के आसपास डिज़ाइन किया गया है। वास्तव में, कुछ सिम बनाने में शामिल अधिकांश काम आपके डेटा को पुनर्व्यवस्थित कर रहा है ताकि यह संगत और वेक्टरिज़ेबल हो। तो करने के लिए सबसे अच्छी बात यह है कि आप अपने डेटा संरचनाओं को पुनर्व्यवस्थित करें ताकि आप उन्हें एक समय में 16 बाइट्स लिख सकें। यह न भूलें कि आप उन्हें स्मृति के लिए प्रतिबद्ध करने से पहले अपने सिमड वेक्टर के अंदर घटकों को पुन: व्यवस्थित कर सकते हैं।

विफल होने पर, PEXTRW सेशन (_mm_extract_epi16 आंतरिक) एक एसएसई रजिस्टर से छोटा खींचने और एक पूर्णांक रजिस्टर में स्टोर करने का एकमात्र तरीका है। आपके लिए उपलब्ध दूसरा दृष्टिकोण अनपॅक और शफल ऑप्स (_mm_shuffle_ps इत्यादि) को रजिस्टर के निम्न शब्द में घुमाने के लिए और फिर MOVSS/_mm_store_ss() को उस शब्द को एक समय में स्मृति में संग्रहीत करने के लिए उपयोग करना है। hit - - store स्टाल

तुम शायद मिलेगा एक सूक्ष्म सीपीयू कार्यान्वयन विस्तार की वजह से एक संघ का उपयोग कर, या SSE और सामान्य प्रयोजन रजिस्टरों के बीच डेटा ले कि, बहुत खराब प्रदर्शन प्रदान करेगा एक load कहा जाता है।असल में, रजिस्टर प्रकारों के बीच डेटा को स्थानांतरित करने का कोई सीधा तरीका नहीं है; प्रोसेसर को पहले एसएसई डेटा को स्मृति में लिखना होता है, और उसके बाद इसे फिर से जीपीआर में पढ़ा जाता है। कई मामलों में, इसका मतलब है कि इसे लोड ऑपरेशन को रोकना होगा और जब तक स्टोर आगे बढ़ने से पहले स्टोर साफ़ नहीं हो जाता तब तक प्रतीक्षा करें।

+0

स्पष्टीकरण के लिए धन्यवाद। जब आप कहते हैं कि मैं सिम वेक्टर में घटकों को पुन: व्यवस्थित कर सकता हूं, तो क्या आप अनपॅक और शफल ऑप्स का जिक्र कर रहे हैं? – Scott

+0

हाँ, ठीक है तो। – Crashworks

+1

और यह न भूलें कि आप मास्क किए गए चाल/शफल का भी उपयोग कर सकते हैं। उदाहरण के लिए, यदि आपके पास एसएसई एक = <'ABCD'> पंजीकृत है जिसे आप मेमोरी लाइन 'XYZW' पर लिखना चाहते हैं, जैसे कि केवल पहले और तीसरे शब्दों को ओवरराइट किया गया था (स्मृति में' AYCW' 'प्रदान करना), तो आप गंतव्य रेखा को लोड कर सकते हैं b = 'XYZW' पंजीकृत करें, उन्हें एक मुखौटा-चाल के साथ गठबंधन करें c = (एबीसीडी और 1010) | (XYZW और 0101) = AYCW, और उसके बाद सी को वापस स्मृति में सहेजें। – Crashworks

2

मुझे विशेष रूप से एसएसई के बारे में पता नहीं है, लेकिन आमतौर पर वेक्टरिज्ड इकाइयों का पूरा बिंदु यह है कि वे बहुत तेजी से काम कर सकते हैं बशर्ते डेटा विशेष संरेखण और स्वरूपण का पालन करता हो। तो यह सही प्रारूप और संरेखण में डेटा प्रदान करने और निकालने के लिए आप पर निर्भर है।

0

आप बाइट निकालने के लिए यूनियन का उपयोग करने का प्रयास कर सकते हैं।

union 
{ 
    float value; 
    unsigned char ch[8]; 
}; 

और फिर आवश्यकतानुसार
के साथ संघ-विचार खेलते हैं चारों ओर, शायद अहस्ताक्षरित चार ch की जगह बाइट्स आवंटित [8] एक गुमनाम struct के साथ?
हो सकता है कि आप कुछ और अधिक विचार here

+0

मैंने सोचा कि संघ को सीधे एक्सेस करना बुरा व्यवहार था? – Scott

+0

मुझे इसके बारे में पता नहीं है; सबसे आसान प्रभावी समाधान हर बार – slashmais

+0

पर अपना वोट प्राप्त करता है इस मामले को छोड़कर यह एक विशाल लोड-हिट-स्टोर स्टॉल को प्रेरित करता है। – Crashworks

2

SSE से बिखराव नहीं है/कार्यक्षमता कि आप की आवश्यकता इकट्ठा होते हैं, मिल, हालांकि यह शायद भविष्य SIMD आर्किटेक्चर में आ रहा है कर सकते हैं।

जैसा कि पहले ही सुझाव दिया गया है, तो आप एक संघ, जैसे उपयोग कर सकते हैं:

typedef union 
{ 
    __m128i v; 
    uint8_t a8[16]; 
    uint16_t a16[8]; 
    uint32_t a32[4]; 
} U128; 

आदर्श रूप में हेरफेर के इस प्रकार केवल किसी भी महत्वपूर्ण छोरों बाहर होता है, यह सन्निहित डेटा तत्वों पर सीधा SIMD संचालन की तुलना में बहुत अक्षम है के रूप में ।