2010-09-09 7 views
5

मेरी छवि प्रसंस्करण परियोजना ग्रेस्केल छवियों के साथ काम करती है। मेरे पास एआरएम कॉर्टेक्स-ए 8 प्रोसेसर प्लेटफार्म है। मैं नीयन का उपयोग करना चाहता हूं।uint32_t के रूप में 8bit uint8_t लोड करें?

मेरे पास एक ग्रेस्केल छवि है (नीचे दिए गए उदाहरण पर विचार करें) और मेरे एल्गोरिदम में, मुझे केवल कॉलम जोड़ना होगा।

मैं चार 8-बिट पिक्सेल कैसे लोड कर सकते हैं समानांतर में, जो uint8_t हैं को महत्व देता है, चार uint32_t 128 बिट नियोन रजिस्टरों में से एक में के रूप में? ऐसा करने के लिए मुझे क्या अंतर्निहित उपयोग करना है?

मेरा मतलब है:

alt text

मैं उन्हें 32 बिट के रूप में लोड करना होगा क्योंकि अगर आप ध्यान से देखो, इस समय मैं कर 255 + 255 512 है, जो एक 8 बिट में नहीं ठहराया जा सकता है रजिस्टर।

उदा।

255 255 255 255 ......... (640 pixels) 
255 255 255 255 
255 255 255 255 
255 255 255 255 
. 
. 
. 
. 
. 
(480 pixels) 
+2

255 + 255 = 510। – kennytm

उत्तर

11

मैं अनुशंसा करता हूं कि आप एआरएम पर सिम काम कैसे करते हैं, यह समझने में थोड़ा सा समय व्यतीत करें। देखो पर:

पर एक नज़र डालें:

  1. http://blogs.arm.com/software-enablement/161-coding-for-neon-part-1-load-and-stores/
  2. http://blogs.arm.com/software-enablement/196-coding-for-neon-part-2-dealing-with-leftovers/
  3. http://blogs.arm.com/software-enablement/241-coding-for-neon-part-3-matrix-multiplication/
  4. http://blogs.arm.com/software-enablement/277-coding-for-neon-part-4-shifting-left-and-right/

आप आरंभ करने के लिए। फिर आप डोमेन द्वारा अनुशंसित इनलाइन असेंबलर या संबंधित एआरएम इंट्रिनिक्स का उपयोग करके अपने सिम कोड को कार्यान्वित कर सकते हैं।

3

यदि आपको 480 8-बिट मानों तक पहुंचने की आवश्यकता है तो आपको तकनीकी रूप से 17 बिट इंटरमीडिएट स्टोरेज की आवश्यकता होगी। हालांकि, यदि आप दो चरणों में जोड़ों को निष्पादित करते हैं, यानि, शीर्ष 240 पंक्तियों के नीचे 240 पंक्तियों के नीचे, आप इसे 16-बिट्स में कर सकते हैं। फिर आप अंतिम जवाब प्राप्त करने के लिए दो हिस्सों से परिणाम जोड़ सकते हैं।

वास्तव में एक नियॉन निर्देश है जो आपके एल्गोरिदम के लिए उपयुक्त है जिसे vaddw कहा जाता है। यह एक क्विक वेक्टर में एक डॉक्स वेक्टर जोड़ देगा, जिसमें बाद वाले तत्व होते हैं जो पूर्व के रूप में चौड़े होते हैं। आपके मामले में, vaddw.u8 का उपयोग 8 पिक्सेल से 8 16-बिट संचयकों को जोड़ने के लिए किया जा सकता है। फिर, 8 32-बिट वाले एक सेट में 8 16-बिट accumulators के दो सेट जोड़ने के लिए vaddw.u16 का उपयोग किया जा सकता है - ध्यान दें कि आपको दोनों हिस्सों को प्राप्त करने के लिए दो बार निर्देश का उपयोग करना होगा।

यदि आवश्यक हो, तो आप vmovn या vqmovn का उपयोग कर मानों को वापस 16-बिट या 8-बिट में परिवर्तित कर सकते हैं।

2

ऐसा कोई निर्देश नहीं है जो आपके 4 8 बिट मान को 4 32 बिट रजिस्टर में लोड कर सके।

आपको उन्हें लोड करना होगा और फिर दो बार एक वीएसएलएल का उपयोग करना होगा। क्योंकि नियॉन 32 रजिस्टरों का उपयोग नहीं कर सकता है, आपको 8 पिक्सेल (और 4 नहीं)

पर काम करना होगा, आप केवल 16 बिट रजिस्टर का उपयोग कर सकते हैं। यह पर्याप्त होना चाहिए ...

0

एक क्यू-रजिस्टर में एकल-लेन भार निर्देश (vld1 <register>[<lane>], [<address]) का उपयोग करके 4 बाइट लोड करें, फिर पहले 16 को बढ़ावा देने के लिए दो चाल-लंबे निर्देश (vmovl) का उपयोग करें और फिर 32 बिट परिणाम (जीएनयू में सिंटेक्स) कुछ

vld1 d0[0], [<address>] @Now d0 = (*<addr>, *<addr+1>, *<addr+2>, *<addr+3>, <junk>, ... <junk>) 
vmovl.u8 q0, d0 @Now q1 = (d0, d1) = ((uint16_t)*<addr>, ... (uint16_t)*<addr+3>, <junk>, ... <junk>) 
vmovl.u16 q0, d2 @Now d0 = ((uint32_t)*<addr>, ... (uint32_t)*<addr+3>), d1 = (<junk>, ... <junk>) 

आप गारंटी देते हैं तो कर सकते हैं कि <address> 4 बाइट गठबंधन है, तो [<address>: 32] लिखने के बजाय लोड अनुदेश में, एक या दो चक्र को बचाने के लिए किया जाना चाहिए। यदि आप ऐसा करते हैं और पता गठबंधन नहीं है, तो आपको एक गलती मिल जाएगी।

उम, मुझे अभी एहसास हुआ कि आप इंट्राइनिक्स का उपयोग करना चाहते हैं, असेंबली नहीं, इसलिए यहां इंट्रिनिक्स के साथ एक ही बात है।

uint32x4_t v8; // Will actually hold 4 uint8_t 
v8 = vld1_lane_u32(ptr, v8, 0); 
const uint16x4_t v16 = vget_low_u16(vmovl_u8(vreinterpret_u8_u32(v8))); 
const uint32x4_t v32 = vmovl_u16(v16); 
संबंधित मुद्दे