2012-06-27 19 views
10

से अधिकतम गति iOS के लिए मैंने गहन ऐप कंप्यूटिंग किया। बेशक यह धीमा था। लेकिन यह मेरे पीसी प्रोटोटाइप की तुलना में 200 गुना धीमा था। तो मैं इसे अनुकूलित कर रहा था। बहुत पहले 15 सेकंड से मैं 0.4 सेकंड की गति प्राप्त करने में सक्षम था। मुझे आश्चर्य है कि क्या मुझे सभी चीजें मिलती हैं और अन्य लोग क्या साझा करना चाहते हैं। क्या मैंने किया: OpenCV के अंदर करने के लिए "float"आईओएस/आईपैड/आईफोन

  1. बदला "double" डेटा प्रकार। डबल 64 बिट और 32 बिट सीपीयू आसानी से उन्हें संभाल नहीं सकता है, इसलिए फ्लोट ने मुझे कुछ गति दी। ओपनसीवी अक्सर डबल का उपयोग करता है।

  2. कंपाइलर विकल्पों में "-mpfu=neon" जोड़ा गया। साइड इफेक्ट नई समस्या थी कि एमुलेटर कंपाइलर अब और काम नहीं करता है और कुछ भी देशी हार्डवेयर पर ही परीक्षण किया जा सकता है।

  3. sin() और cos() 90 मूल्य लुकअप टेबल के साथ कार्यान्वित किया गया। स्पीडअप बड़ा था! यह पीसी के कुछ हद तक विपरीत है जहां ऐसे अनुकूलन कोई गति नहीं देते हैं। कोड में डिग्री कोड था और यह मान sin() और cos() के लिए रेडियंस में परिवर्तित कर दिया गया था। यह कोड भी हटा दिया गया था। लेकिन लुकअप टेबल ने काम किया।

  4. सक्षम "thumb optimizations"। कुछ ब्लॉग पोस्ट बिल्कुल विपरीत की सलाह देते हैं लेकिन ऐसा इसलिए होता है क्योंकि अंगूठे आमतौर पर armv6 पर धीमी चीजें बनाता है। armv7 किसी भी समस्या से मुक्त है और चीजों को तेज़ और छोटा बनाता है।

  5. यह सुनिश्चित करने के लिए कि अंगूठे अनुकूलन और -mfpu=neon सर्वोत्तम रूप से काम करते हैं और क्रैश पेश नहीं करते हैं, मैंने armv6 लक्ष्य को पूरी तरह से हटा दिया है। मेरा सभी कोड armv7 पर संकलित किया गया है और इसे ऐप स्टोर में आवश्यकता के रूप में भी सूचीबद्ध किया गया है। इसका मतलब है कि न्यूनतम iPhone3GS होगा। मुझे लगता है कि पुराने लोगों को छोड़ना ठीक है। वैसे भी पुराने लोगों में धीमे CPUs और CPU गहन ऐप पुराने डिवाइस पर स्थापित होने पर खराब उपयोगकर्ता अनुभव प्रदान करता है।

  6. बेशक

    मैं -O3 flag

  7. मैं OpenCV से "dead code" नष्ट कर दिया उपयोग करें। अक्सर ओपनसीवी को अनुकूलित करते समय मुझे कोड दिखाई देता है जो मेरी परियोजना के लिए स्पष्ट रूप से आवश्यक नहीं है। उदाहरण के लिए अक्सर पिक्सेल आकार 8 बिट या 32 बिट होने के लिए अतिरिक्त "if()" है और मुझे पता है कि मुझे केवल 8 बिट की आवश्यकता है। यह कुछ कोड हटा देता है, अनुकूलक को कुछ और हटाने या स्थिरांक के साथ प्रतिस्थापित करने का बेहतर मौका प्रदान करता है। कोड भी कैश में बेहतर फिट बैठता है।

कोई अन्य चाल और विचार? मेरे लिए अंगूठे को सक्षम करने और लुकअप के साथ त्रिकोणमिति को बदलने के लिए निर्माताओं को बढ़ावा दिया गया और मुझे आश्चर्य हुआ। शायद आप कुछ और करने के लिए जानते हैं जो ऐप्स को उड़ता है?

उत्तर

13

यदि आप बहुत अधिक फ़्लोटिंग पॉइंट गणना कर रहे हैं, तो इससे आपको ऐप्पल के Accelerate ढांचे का उपयोग करने के लिए बहुत फायदा होगा। यह समानांतर में वैक्टरों पर गणना करने के लिए फ़्लोटिंग पॉइंट हार्डवेयर का उपयोग करने के लिए डिज़ाइन किया गया है।

मैं भी एक-एक करके अपने अंक संबोधित करेंगे:

1) यह सीपीयू की वजह से नहीं है, यह क्योंकि ARMv7 युग केवल 32-बिट चल बिन्दु आपरेशनों चल में गणना की जाएगी के रूप में है प्वाइंट प्रोसेसर हार्डवेयर (क्योंकि सेब हार्डवेयर को बदल दिया गया है)। इसके बजाए 64-बिट वाले की गणना की जाएगी। बदले में, 32-बिट ऑपरेशन बहुत तेज हो गए।

2) नियोन नई फ्लोटिंग बिंदु प्रोसेसर शिक्षा का नाम

3 सेट) हाँ, यह एक अच्छी तरह से ज्ञात विधि है। ऐप्पल के ढांचे का उपयोग करने का एक विकल्प है जिसका मैंने उपरोक्त उल्लेख किया है। यह पाप और कॉस फ़ंक्शन प्रदान करता है जो समांतर में 4 मानों की गणना करते हैं। एल्गोरिदम असेंबली और नीयन में ठीक से ट्यून किए जाते हैं ताकि वे न्यूनतम बैटरी का उपयोग करते समय अधिकतम प्रदर्शन दें।

4) अंगूठे के नए armv7 कार्यान्वयन में armv6 की कमी नहीं है। अक्षम करने की सिफारिश केवल v6 पर लागू होती है।

5) हां, 80% उपयोगकर्ताओं को आईओएस 5.0 या उससे ऊपर के समय पर विचार करना है (armv6 डिवाइस 4.2.1 पर समर्थन समाप्त कर चुके हैं), जो ज्यादातर स्थितियों के लिए पूरी तरह से स्वीकार्य है।

6) जब आप रिलीज मोड में बनाते हैं तो यह स्वचालित रूप से होता है।

7) हां, हालांकि उपरोक्त तरीकों के रूप में इसका प्रभाव उतना बड़ा नहीं होगा।

मेरी सिफारिश त्वरित जांचने के लिए है। इस तरह आप यह सुनिश्चित कर सकते हैं कि आप फ़्लोटिंग पॉइंट प्रोसेसर की पूरी शक्ति का लाभ उठा रहे हैं।

+0

यह त्वरण मेरे लिए नया था। यह अभी भी उपयोग करना मुश्किल है क्योंकि इसे असेंबली-स्तर की सोच की जरूरत है। लेकिन अभी भी संभव है और शायद कोशिश करने जा रहा है। मैं इसे बाद में स्वीकार करता हूं क्योंकि मैं देखना चाहता हूं कि हमें यहां अधिक उपयोगी संकेत मिलते हैं या नहीं। –

+1

डब्ल्यूडब्ल्यूडीसी 2012 वीडियो में एक सत्र है जो पूरी तरह से त्वरित ढांचे के साथ सौदा करता है। आपको इसे देखना चाहिए ^^ – borrrden

+0

http://adcdownload.apple.com//wwdc_2012/wwdc_2012_session_pdfs/session_708__the_accelerate_framework.pdf और https://developer.apple.com/videos/wwdc/2012/#708 प्रतीत होता है इसके लिए लिंक होने के लिए –

1

मैं पिछली पोस्ट पर कुछ प्रतिक्रिया प्रदान करता हूं। यह कुछ विचार बताता है कि मैंने बिंदु 7 में मृत कोड प्रदान करने का प्रयास किया था। यह थोड़ा व्यापक विचार था। मुझे स्वरूपण की आवश्यकता है, इसलिए कोई टिप्पणी फ़ॉर्म इस्तेमाल नहीं किया जा सकता है। ऐसा कोड ओपनसीवी में था:

for(kk = 0; kk < (int)(descriptors->elem_size/sizeof(vec[0])); kk++) { 
    vec[kk] = 0; 
} 

मैं देखना चाहता था कि यह असेंबली पर कैसा दिखता है। यकीन है कि मैं विधानसभा में पा सकते हैं बनाने के लिए, मैं इसे इस तरह लपेटा:

__asm__("#start"); 
for(kk = 0; kk < (int)(descriptors->elem_size/sizeof(vec[0])); kk++) { 
    vec[kk] = 0; 
} 
__asm__("#stop"); 

अब मैं प्रेस "उत्पाद -> आउटपुट उत्पन्न -> विधानसभा फ़ाइल" और मैं क्या मिलता है:

@ InlineAsm Start 
    #start 
    @ InlineAsm End 
Ltmp1915: 
    ldr r0, [sp, #84] 
    movs r1, #0 
    ldr r0, [r0, #16] 
    ldr r0, [r0, #28] 
    cmp r0, #4 
    mov r0, r4 
    blo LBB14_71 
LBB14_70: 
Ltmp1916: 
    ldr r3, [sp, #84] 
    movs r2, #0 
Ltmp1917: 
    str r2, [r0], #4 
    adds r1, #1 
Ltmp1918: 
Ltmp1919: 
    ldr r2, [r3, #16] 
    ldr r2, [r2, #28] 
    lsrs r2, r2, #2 
    cmp r2, r1 
    bgt LBB14_70 
LBB14_71: 
Ltmp1920: 
    add.w r0, r4, #8 
    @ InlineAsm Start 
    #stop 
    @ InlineAsm End 

बहुत सारे कोड मैं बाहर (int)(descriptors->elem_size/sizeof(vec[0])) का मूल्य printf डी और यह हमेशा 64 तो मैं 64 होने के लिए यह hardcoded था और कोडांतरक के माध्यम से फिर से पारित कर दिया:

@ InlineAsm Start 
    #start 
    @ InlineAsm End 
Ltmp1915: 
    vldr.32 s16, LCPI14_7 
    mov r0, r4 
    movs r1, #0 
    mov.w r2, #256 
    blx _memset 
    @ InlineAsm Start 
    #stop 
    @ InlineAsm End 

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

__asm__("#start"); 
vDSP_vclr(vec,1,64); 
__asm__("#stop"); 

विधानसभा अब लग रहा है:

मैं भी रूप के साथ तीन लाइनों की जगह सुझाव में तेजी लाने की कोशिश की

@ InlineAsm Start 
    #start 
    @ InlineAsm End 
Ltmp1917: 
    str r1, [r7, #-140] 
Ltmp1459: 
Ltmp1918: 
    movs r1, #1 
    movs r2, #64 
    blx _vDSP_vclr 
Ltmp1460: 
Ltmp1919: 
    add.w r0, r4, #8 
    @ InlineAsm Start 
    #stop 
    @ InlineAsm End 

अनिश्चित अगर यह bzero की तुलना में तेजी है, हालांकि। मेरे संदर्भ में इस भाग में अधिक समय नहीं है और दो प्रकार एक ही गति पर काम करना प्रतीत होता है।

एक और चीज जिसे मैंने सीखा है वह GPU का उपयोग कर रहा है। इसके बारे में अधिक जानकारी http://www.sunsetlakesoftware.com/2012/02/12/introducing-gpuimage-framework