क्या कोई विशेषता है जिसे मैं संकलक को बताने के लिए उपयोग कर सकता हूं कि एक विधि को हमेशा अनुकूलित किया जाना चाहिए, भले ही वैश्विक /o+
कंपाइलर स्विच सेट न हो?क्या मैं संकलक को एक विशिष्ट विधि को अनुकूलित करने के लिए मजबूर कर सकता हूं?
कारण मैं पूछता हूं क्योंकि मैं मौजूदा विधि के आईएल कोड के आधार पर गतिशील रूप से एक विधि बनाने के विचार से टकरा रहा हूं; मैनिपुलेशन मैं करना चाहता हूं जब कोड अनुकूलित किया जाता है, लेकिन संकलक द्वारा उत्पन्न अतिरिक्त निर्देशों के कारण गैर-अनुकूलित कोड में काफी कठिन हो जाता है।
संपादित करें: गैर अनुकूलन नहीं है जो मुझे परेशान बारे में अधिक जानकारी ...
के भाज्य समारोह के निम्नलिखित कार्यान्वयन पर ध्यान दें:
static long FactorialRec(int n, long acc)
{
if (n == 0)
return acc;
return FactorialRec(n - 1, acc * n);
}
(नोट: मैं वहाँ पता फैक्टोरियल की गणना करने के बेहतर तरीके हैं, यह सिर्फ एक उदाहरण है)
आईएल अनुकूलन के साथ जेनरेट किया गया I काफी सरल है:
IL_0000: ldarg.0
IL_0001: brtrue.s IL_0005
IL_0003: ldarg.1
IL_0004: ret
IL_0005: ldarg.0
IL_0006: ldc.i4.1
IL_0007: sub
IL_0008: ldarg.1
IL_0009: ldarg.0
IL_000A: conv.i8
IL_000B: mul
IL_000C: call UserQuery.FactorialRec
IL_0011: ret
लेकिन unoptimized संस्करण काफी अलग
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.0
IL_0003: ceq
IL_0005: ldc.i4.0
IL_0006: ceq
IL_0008: stloc.1
IL_0009: ldloc.1
IL_000A: brtrue.s IL_0010
IL_000C: ldarg.1
IL_000D: stloc.0
IL_000E: br.s IL_001F
IL_0010: ldarg.0
IL_0011: ldc.i4.1
IL_0012: sub
IL_0013: ldarg.1
IL_0014: ldarg.0
IL_0015: conv.i8
IL_0016: mul
IL_0017: call UserQuery.FactorialRec
IL_001C: stloc.0
IL_001D: br.s IL_001F
IL_001F: ldloc.0
IL_0020: ret
यह केवल एक ही निकास बिंदु के लिए डिज़ाइन किया गया है अंत में है। वापसी का मूल्य स्थानीय चर में संग्रहीत किया जाता है।
यह एक मुद्दा क्यों है? मैं गतिशील रूप से एक विधि उत्पन्न करना चाहता हूं जिसमें पूंछ कॉल अनुकूलन शामिल है। रिकर्सिव कॉल से पहले tail.
उपसर्ग जोड़कर अनुकूलित विधि को आसानी से संशोधित किया जा सकता है, क्योंकि ret
को छोड़कर कॉल के बाद कुछ भी नहीं है। लेकिन unoptimized संस्करण के साथ, मुझे इतना यकीन नहीं है ... रिकर्सिव कॉल का परिणाम स्थानीय चर में संग्रहीत किया जाता है, फिर एक बेकार शाखा है जो सिर्फ अगले निर्देश पर कूद जाती है, स्थानीय चर लोड हो जाता है और लौटाया जाता है। तो मेरे पास यह जांचने का कोई आसान तरीका नहीं है कि रिकर्सिव कॉल वास्तव में अंतिम निर्देश है, इसलिए मुझे यकीन नहीं है कि पूंछ कॉल अनुकूलन लागू किया जा सकता है।
AFAIK, नहीं - यह संभव नहीं है –
जेआईटी कंपाइलर हमेशा हर विधि को अनुकूलित करेगा। – Steven
@Steven, अगर आप इसे नहीं बताते हैं (उदा। 'MethodImplAttribute'' में 'NoOptimization' ध्वज के साथ)। लेकिन वैसे भी, मेरा प्रश्न संकलक अनुकूलन के बारे में है, जेआईटी अनुकूलन नहीं, क्योंकि मुझे उत्पन्न आईएल कोड में रूचि है। –