Android / ARM के टारगेट के लिए डेल्फी XEx कोड जनरेशन को कैसे प्रभावित करें?


266

2017-05-17 को अपडेट करें। मैं अब उस कंपनी के लिए काम नहीं करता जहां यह प्रश्न उत्पन्न हुआ है, और डेल्फी एक्सएक्सएक्स तक पहुंच नहीं है। जब मैं वहां था, समस्या को मिश्रित एफपीसी + जीसीसी (पास्कल + सी) में माइग्रेट करके हल किया गया था, जहां कुछ रूटीन के लिए नियॉन इंट्रिंसिक्स के साथ इसमें अंतर हुआ। (FPC + GCC की अत्यधिक अनुशंसा की जाती है क्योंकि यह मानक उपकरण, विशेष रूप से Valgrind का उपयोग करने में सक्षम बनाता है।) यदि कोई व्यक्ति विश्वसनीय उदाहरणों के साथ प्रदर्शित कर सकता है, तो वे वास्तव में डेल्फी एक्सएक्सएक्स से अनुकूलित एआरएम कोड का उत्पादन कैसे कर सकते हैं, मुझे उत्तर स्वीकार करने में खुशी हो रही है। ।


Embarcadero के डेल्फी कंपाइलर Android उपकरणों के लिए देशी ARM कोड बनाने के लिए LLVM बैकएंड का उपयोग करते हैं। मेरे पास बड़ी मात्रा में पास्कल कोड हैं जिन्हें मुझे एंड्रॉइड एप्लिकेशन में संकलित करने की आवश्यकता है और मैं यह जानना चाहूंगा कि डेल्फी को अधिक कुशल कोड कैसे बनाया जाए। अभी, मैं स्वचालित सिमडी अनुकूलन जैसी उन्नत सुविधाओं के बारे में बात नहीं कर रहा हूं, बस उचित कोड के उत्पादन के बारे में। निश्चित रूप से एलएलवीएम पक्ष के मापदंडों को पारित करने का एक तरीका होना चाहिए, या किसी तरह परिणाम को प्रभावित करना चाहिए? आमतौर पर, किसी भी संकलक के पास कोड संकलन और अनुकूलन को प्रभावित करने के लिए कई विकल्प होंगे, लेकिन डेल्फी के एआरएम लक्ष्य सिर्फ "अनुकूलन / बंद" और ऐसा लगता है।

LLVM यथोचित तंग और समझदार कोड का उत्पादन करने में सक्षम माना जाता है, लेकिन ऐसा लगता है कि डेल्फी अपनी सुविधाओं का उपयोग एक अजीब तरीके से कर रहा है। डेल्फी स्टैक का बहुत अधिक उपयोग करना चाहता है, और यह आमतौर पर प्रोसेसर के रजिस्टरों r0-r3 का उपयोग अस्थायी चर के रूप में करता है। शायद सभी का पागलपन, यह चार 1-बाइट लोड संचालन के रूप में सामान्य 32 बिट पूर्णांक लोड हो रहा है। डेल्फी को बेहतर एआरएम कोड का उत्पादन कैसे करें, और बाइट-बाय-बाइट की परेशानी के बिना यह एंड्रॉइड के लिए बना रहा है?

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

आइए इस सरल कार्य को देखें:

function ReadInteger(APInteger : PInteger) : Integer;
begin
  Result := APInteger^;
end;

यहां तक ​​कि अद्यतन पैक 1 के साथ डेल्फी XE7, साथ ही साथ XE6 पर स्विच किए गए अनुकूलन के साथ, उस फ़ंक्शन के लिए निम्न एआरएम असेंबली कोड का उत्पादन करें:

Disassembly of section .text._ZN16Uarmcodetestform11ReadIntegerEPi:

00000000 <_ZN16Uarmcodetestform11ReadIntegerEPi>:
   0:   b580        push    {r7, lr}
   2:   466f        mov r7, sp
   4:   b083        sub sp, #12
   6:   9002        str r0, [sp, #8]
   8:   78c1        ldrb    r1, [r0, #3]
   a:   7882        ldrb    r2, [r0, #2]
   c:   ea42 2101   orr.w   r1, r2, r1, lsl #8
  10:   7842        ldrb    r2, [r0, #1]
  12:   7803        ldrb    r3, [r0, #0]
  14:   ea43 2202   orr.w   r2, r3, r2, lsl #8
  18:   ea42 4101   orr.w   r1, r2, r1, lsl #16
  1c:   9101        str r1, [sp, #4]
  1e:   9000        str r0, [sp, #0]
  20:   4608        mov r0, r1
  22:   b003        add sp, #12
  24:   bd80        pop {r7, pc}

बस निर्देश की संख्या और स्मृति तक पहुँचने के लिए डेल्फी की जरूरत है कि गिनती। और 4 सिंगल-बाइट लोड से 32 बिट पूर्णांक का निर्माण ... अगर मैं फ़ंक्शन को थोड़ा बदल देता हूं और एक पॉइंटर के बजाय एक var पैरामीटर का उपयोग करता हूं, तो यह थोड़ा कम जटिल है:

Disassembly of section .text._ZN16Uarmcodetestform14ReadIntegerVarERi:

00000000 <_ZN16Uarmcodetestform14ReadIntegerVarERi>:
   0:   b580        push    {r7, lr}
   2:   466f        mov r7, sp
   4:   b083        sub sp, #12
   6:   9002        str r0, [sp, #8]
   8:   6801        ldr r1, [r0, #0]
   a:   9101        str r1, [sp, #4]
   c:   9000        str r0, [sp, #0]
   e:   4608        mov r0, r1
  10:   b003        add sp, #12
  12:   bd80        pop {r7, pc}

मैं यहां डिसएस्पेशन को शामिल नहीं करूंगा, लेकिन iOS के लिए, डेल्फी पॉइंटर और var पैरामीटर संस्करणों के लिए समान कोड का उत्पादन करता है, और वे लगभग नहीं बल्कि एंड्रॉइड वर्जन पैरामीटर संस्करण के समान हैं। संपादित करें: स्पष्ट करने के लिए, बाइट-बाय-बाइट लोडिंग केवल एंड्रॉइड पर है। और केवल एंड्रॉइड पर, सूचक और var पैरामीटर संस्करण एक दूसरे से भिन्न होते हैं। IOS पर दोनों वर्जन बिलकुल समान कोड जनरेट करते हैं।

तुलना के लिए, यहां FPC 2.7.1 (मार्च 2014 से SVN ट्रंक संस्करण) अनुकूलन स्तर -O2 के साथ फ़ंक्शन के बारे में सोचता है। सूचक और var पैरामीटर संस्करण बिल्कुल समान हैं।

Disassembly of section .text.n_p$armcodetest_$$_readinteger$pinteger$$longint:

00000000 <P$ARMCODETEST_$$_READINTEGER$PINTEGER$$LONGINT>:

   0:   6800        ldr r0, [r0, #0]
   2:   46f7        mov pc, lr

मैंने एंड्रॉइड NDK के साथ आने वाले C कंपाइलर के साथ एक समतुल्य C फ़ंक्शन का परीक्षण किया।

int ReadInteger(int *APInteger)
{
    return *APInteger;
}

और यह अनिवार्य रूप से उसी चीज को संकलित करता है जिसे एफपीसी ने बनाया है:

Disassembly of section .text._Z11ReadIntegerPi:

00000000 <_Z11ReadIntegerPi>:
   0:   6800        ldr r0, [r0, #0]
   2:   4770        bx  lr

14
इस बारे में Google+ चर्चा में Btw , सैम शॉ नोट करता है कि सी ++ डिबग बिल्ड में लंबी-फ़ॉर्म कोड और रिलीज़ में अनुकूलित कोड दिखाता है। व्हेल्स डेल्फी इसे दोनों में करती है। तो इससे यह अच्छी तरह से झंडे में एक साधारण बग हो सकता है जिसे वे एलएलवीएम भेज रहे हैं, और यदि एक बग रिपोर्ट दाखिल करने के लिए बहुत लायक है, तो यह बहुत जल्द ठीक हो सकता है।
डेविड

9
ओह, ठीक है, मैंने गलत पढ़ा। फिर, जैसा कि नॉटलीकेट ने कहा, ऐसा लगता है कि यह इंगित करता है कि पॉइंटर लोड अनलग्ड (या संरेखण की गारंटी नहीं दे सकता है), और पुराने एआरएम प्लेटफॉर्म जरूरी नहीं कि अनलग्ड लोड कर सकते हैं। सुनिश्चित करें कि आपने armeabi-v7aइसके बजाय लक्ष्यीकरण का निर्माण किया है armeabi(यह सुनिश्चित नहीं है कि इस संकलक में ऐसे विकल्प हैं), चूंकि ARMv6 (जबकि armeabiARMv5 को मानता है) के बाद अनलग्टेड लोड का समर्थन किया जाना चाहिए । (दिखाया गया डिस्सैम्ड ऐसा नहीं लगता है कि यह एक बिगेंडियन वैल्यू पढ़ता है, यह सिर्फ एक बार में एक छोटे से बाइट मूल्य को पढ़ता है।)
mstorsjo

6
मुझे RSP-9922 मिला, जो कि यह वही बग प्रतीत होता है।
डेविड

6
किसी ने XE4 और XE5 के बीच होने वाले अनुकूलन के बारे में पूछा था, embarcadero.public.delphi.platformspecific.ios न्यूज़ग्रुप में, "एआरएम कंपाइलर ऑप्टिमाइज़ेशन टूट गया?" devsuperpage.com/search/…
साइड एस। फ्रेश

6
@ जोहान: क्या निष्पादन योग्य है? मुझे आभास था कि यह डेल्फी के संकलक निष्पादन के अंदर किसी तरह बेक किया गया था। इसे आजमाएं और हमें परिणाम बताएं।
साइड एस। फ्रेश

जवाबों:


8

हम मामले की जांच कर रहे हैं। संक्षेप में, यह एक सूचक द्वारा संदर्भित पूर्णांक के संभावित गलत संरेखण (32 सीमा तक) पर निर्भर करता है। सभी उत्तरों के लिए थोड़ा और समय चाहिए ... और इस पर ध्यान देने की योजना है।

मार्को कैंट, डेल्फी डेवलपर्स पर मध्यस्थ

यह भी संदर्भ क्यों डेल्फी zlib और ज़िप पुस्तकालयों 64 बिट के तहत इतना धीमा कर रहे हैं? Win64 पुस्तकालयों को अनुकूलन के बिना बनाया गया है।


QP रिपोर्ट में: संकलक द्वारा उत्पादित RSP-9922 बुरा ARM कोड, $ O निर्देश को अनदेखा किया गया? , मार्को ने स्पष्टीकरण के बाद जोड़ा:

यहाँ कई मुद्दे हैं:

  • जैसा कि संकेत दिया गया है, अनुकूलन सेटिंग्स केवल संपूर्ण इकाई फ़ाइलों पर लागू होती हैं और व्यक्तिगत कार्यों के लिए नहीं। सीधे शब्दों में कहें, एक ही फाइल में ऑप्टिमाइज़ेशन को चालू और बंद करने से कोई प्रभाव नहीं पड़ेगा।
  • इसके अलावा, बस "डीबग जानकारी" सक्षम होने से अनुकूलन बंद हो जाता है। इस प्रकार, जब कोई डिबगिंग कर रहा होता है, तो स्पष्ट रूप से अनुकूलन चालू करने से कोई प्रभाव नहीं पड़ेगा। नतीजतन, आईडीई में सीपीयू दृश्य अनुकूलित कोड का एक अव्यवस्थित दृश्य प्रदर्शित करने में सक्षम नहीं होगा।
  • तीसरा, गैर-संरेखित 64 बिट डेटा लोड करना सुरक्षित नहीं है और इसके परिणामस्वरूप त्रुटियां होती हैं, इसलिए अलग-अलग 4 एक बाइट संचालन जो दिए गए परिदृश्यों में आवश्यक हैं।

मार्को कैंटो ने जनवरी 2015 में उस नोट को "हम मामले की जांच कर रहे हैं" पोस्ट किया, और संबंधित बग रिपोर्ट RSP-9922 को जनवरी 2016 में "वर्क्स अस एक्सपेक्टेड" संकल्प के साथ हल किया गया था, और एक उल्लेख है "मार्च 2 पर बंद आंतरिक मुद्दा, 2015 "। मुझे उनके स्पष्टीकरण समझ में नहीं आते हैं।
साइड एस। फ्रेश

1
मैंने मुद्दे के समाधान में एक टिप्पणी जोड़ी।
मार्को कैंट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.