2012-12-14 28 views
7

में 3 लेनों को सारांशित करना मैं एआरएम नियॉन इंट्रिनिक्स (एलएलवीएम, आईओएस) के साथ एक आंतरिक लूप को सदिश कर रहा हूं। मैं आम तौर पर float32x4_t एस का उपयोग कर रहा हूं। मेरी गणना इस वेक्टर में चार फ्लोट्स में से तीन को योग करने की आवश्यकता के साथ समाप्त होती है।नीयन फ्लोट 32x4_t

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

मैं नियॉन प्रोग्रामिंग के लिए नया हूं, और मौजूदा "दस्तावेज" बहुत भयानक है। कोई विचार? धन्यवाद!

उत्तर

2

ऐसा लगता है कि आप अपने अतिरिक्त लेन में शून्य लोड करने के लिए वीएलडी 1 (कुछ संस्करण) का उपयोग करना चाहते हैं (जब तक कि आप इसे पहले से शून्य होने की व्यवस्था नहीं कर सकते), इसके बाद दो वीपीएडीडीएल निर्देशों को जोड़कर चार लेन में दो लेन और फिर एक में दो लेन।

3

क्या आप चौथे तत्व को शून्य-आउट कर सकते हैं? शायद इसे कॉपी करके और vset_lane_f32 का उपयोग करके? हालांकि आप से यह वास्तव में करता है में कुछ अधिक परिश्रम की जरूरत है

float32x2_t r = vadd_f32(vget_high_f32(input), vget_low_f32(input)); 
return vget_lane_f32(vpadd_f32(r, r), 0); // vpadd adds adjacent elements 

, तो यह सिर्फ करने के लिए तेजी से हो सकता है vget_lane_f32 के साथ तीन तैरता निकालने और जोड़ें:

यदि हां, तो आप की तरह Sum all elements in a quadword vector in ARM assembly with NEON से जवाब का उपयोग कर सकते उन्हें।

4

आपको ऐसे कार्य के लिए वीएफपी इकाई का उपयोग करने में सक्षम होना चाहिए। नीयन और वीएफपी एक ही रजिस्टर बैंक को साझा करते हैं, जिसका अर्थ है कि आपको एक इकाई का लाभ उठाने के लिए रजिस्टरों के चारों ओर घूमने की जरूरत नहीं है और उनके पास एक ही रजिस्टर बिट्स के अलग-अलग विचार भी हो सकते हैं।

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204j/ch05s03s02.html

आपका float32x4_t इसलिए यह एक क्वाड (क्यू) पर बैठना चाहिए रजिस्टर 128 बिट है। यदि आप पूरी तरह से हाथ आंतरिक का उपयोग कर रहे हैं तो आप नहीं जान पाएंगे कि आप किसका उपयोग कर रहे हैं। समस्या यह है कि अगर यह 4 से ऊपर बैठा है, तो वीएफपी इसे उत्सुक पाठक के लिए एक सटीक () के रूप में नहीं देख सकता है: मैंने यह आसान रखा क्योंकि वीएफपी संस्करणों के बीच मतभेद हैं और यह न्यूनतम न्यूनतम आवश्यकता है।)। तो यह सबसे अच्छा होगा अपने float32x4_tQ0 की तरह एक निश्चित रजिस्टर करने के लिए स्थानांतरित करने के लिए होगा। इसके बाद आप केवल vadd.f32 के साथ एस 0, एस 1, एस 2 जैसे रजिस्टरों को जोड़ सकते हैं और परिणाम को एआरएम रजिस्टर में ले जा सकते हैं।

कुछ चेतावनी ... VFP और नियोन एक ही रजिस्टर बैंक और पाइप लाइन को साझा करने के सैद्धांतिक रूप से अलग निष्पादन इकाइयां हैं। मुझे यकीन नहीं है कि यह दृष्टिकोण दूसरों की तुलना में बेहतर है, मुझे फिर से कहना जरूरी नहीं है, आपको बेंचमार्क करना चाहिए। इसके अलावा यह दृष्टिकोण नियॉन आंतरिक के साथ सुव्यवस्थित नहीं है, इसलिए आपको शायद इनलाइन असेंबली के साथ अपना कोड तैयार करना होगा।

मैं इस तरह देख सकते हैं कि कैसे को देखने के लिए एक सरल टुकड़ा था और मैं इस के साथ आ गया है:

#include "arm_neon.h" 

float32_t sum3() {   
     register float32x4_t v asm ("q0"); 
     float32_t ret; 

     asm volatile(
     "vadd.f32  s0, s1\n" 
     "vadd.f32  s0, s2\n" 
     "vmov   %[ret], s0\n" 
     : [ret] "=r" (ret) 
     : 
     :); 

     return ret; 
} 

इसके बारे में objdump लगता है कि (जीसीसी के साथ संकलित -O3 -mfpu = नीयन -mfloat- abi = softfp)

00000000 <sum3>: 
    0: ee30 0a20 vadd.f32 s0, s0, s1 
    4: ee30 0a01 vadd.f32 s0, s0, s2 
    8: ee10 3a10 vmov r0, s0 
    c: 4770  bx lr 
    e: bf00  nop 

यदि आप इसे जाने देते हैं तो मैं वास्तव में आपके इंप्रेशन सुनना चाहूंगा!