C # JIT संकलन और .NET


86

मैं JIT संकलक कैसे काम करता है के विवरण के बारे में थोड़ा भ्रमित हो गया हूं। मुझे पता है कि C # IL के लिए संकलित है। पहली बार इसे चलाने के लिए यह JIT'd है। क्या इसमें मूल कोड में अनुवादित होना शामिल है? क्या .NET रनटाइम (वर्चुअल मशीन के रूप में?) JIT'd कोड के साथ इंटरैक्ट करता है? मुझे पता है कि यह अनुभवहीन है, लेकिन मैंने वास्तव में खुद को भ्रमित किया है। मेरी धारणा हमेशा यह रही है कि विधानसभाओं की व्याख्या .NET रनटाइम द्वारा नहीं की जाती है, लेकिन मैं बातचीत के विवरण को नहीं समझता।

जवाबों:


83

हां, JIT'ing IL कोड में IL को देशी मशीन निर्देशों में अनुवाद करना शामिल है।

हाँ, .NET रनटाइम JIT'ed देशी मशीन कोड के साथ बातचीत करता है, इस अर्थ में कि रनटाइम देशी मशीन कोड के कब्जे वाले मेमोरी ब्लॉक का मालिक है, रनटाइम मूल मशीन कोड में कॉल करता है, आदि।

आप सही हैं कि .NET रनटाइम आपकी असेंबलियों में IL कोड की व्याख्या नहीं करता है।

क्या होता है जब निष्पादन एक फ़ंक्शन या कोड ब्लॉक तक पहुंचता है (जैसे, एक if ब्लॉक का एक खंड) जो अभी तक जेआईटी को देशी मशीन कोड में संकलित नहीं किया गया है, तो आईआईटी उस ब्लॉक को देशी मशीन कोड में संकलित करने के लिए आमंत्रित किया जाता है। । जब ऐसा हो जाता है, तो प्रोग्राम एग्जीक्यूटिव मशीन लॉजिक को निष्पादित करने के लिए प्रोग्राम एग्जीक्यूटिव मशीन कोड में प्रवेश करता है। अगर उस देशी मशीन कोड को निष्पादित करते समय एक फ़ंक्शन एक फ़ंक्शन कॉल पर पहुंचता है जो अभी तक मशीन कोड के लिए संकलित नहीं किया गया है, तो JIT'r को उस फ़ंक्शन को "बस समय में" संकलित करने के लिए आमंत्रित किया जाता है । और इसी तरह।

जरूरी नहीं कि JIT'r एक फंक्शन बॉडी के सभी लॉजिक को एक बार मशीन कोड में संकलित करे। यदि फ़ंक्शन में स्टेटमेंट्स हैं, तो स्टेटमेंट इफ या फिर क्लॉज़ के ब्लॉक को JIT संकलित नहीं किया जा सकता है जब तक कि निष्पादन वास्तव में उस ब्लॉक से नहीं गुजरता है। कोड पथ जिन्हें निष्पादित नहीं किया गया है वे IL रूप में बने रहते हैं जब तक वे निष्पादित नहीं करते हैं।

संकलित देशी मशीन कोड को स्मृति में रखा जाता है ताकि अगली बार फिर से कोड के अनुभाग का उपयोग किया जा सके। दूसरी बार जब आप किसी फ़ंक्शन को कॉल करते हैं तो यह पहली बार कॉल करने की तुलना में तेज़ी से चलेगा क्योंकि कोई JIT चरण दूसरी बार आवश्यक नहीं है।

डेस्कटॉप .NET में, देशी मशीन कोड को एपडोमैन के जीवनकाल के लिए स्मृति में रखा जाता है। .NET CF में, मूल मशीन कोड को फेंक दिया जा सकता है यदि अनुप्रयोग स्मृति पर कम चल रहा है। अगली बार निष्पादन से मूल आईएल कोड से जेआईटी को फिर से संकलित किया जाएगा।


14
मामूली बाल सुधार एक ही बार में सभी तरीके।
पॉल अलेक्जेंडर

18
जैसा कि ऐसा क्यों किया जाता है, यह मुख्य रूप से है क्योंकि एक गैर-जीट कंपाइलर यह मान नहीं सकता है कि किसी भी लक्षित लक्ष्य पर कुछ अनुकूलन उपलब्ध हैं। एकमात्र विकल्प या तो सामान्य सामान्य भाजक के लिए संकलित हैं, या अधिक सामान्यतः, कई संस्करणों को संकलित करने के लिए, प्रत्येक का अपना मंच है। जेआईटी उस नुकसान को समाप्त करता है क्योंकि मशीन कोड का अंतिम अनुवाद लक्ष्य मशीन पर किया जाता है, जहां कंपाइलर जानता है कि क्या अनुकूलन उपलब्ध हैं।
क्रिस शिन

1
क्रिस, यहां तक ​​कि सोचा कि जेआईटी को पता है कि क्या अनुकूलन उपलब्ध हैं, किसी भी महत्वपूर्ण अनुकूलन को लागू करने का समय नहीं है। संभवतः NGEN अधिक शक्तिशाली है।
ग्रिगोरी

2
@Grigory हाँ, NGEN के पास उस समय का लक्ज़री है जो JIT कंपाइलर नहीं करता है, लेकिन बहुत सारे कोडगेन निर्णय हैं जो JIT संकलित कोड के प्रदर्शन को बेहतर बनाने के लिए कर सकते हैं जो कि पता लगाने में बहुत समय नहीं लेते हैं। उदाहरण के लिए, JIT कंपाइलर JIT कम्पाइलर स्टेप में महत्वपूर्ण समय जोड़े बिना रनटाइम में पाए जाने वाले उपलब्ध हार्डवेयर से सर्वोत्तम मिलान करने के लिए निर्देश सेट का चयन कर सकता है। मुझे नहीं लगता कि .NET JITTER किसी भी महत्वपूर्ण फैशन में ऐसा करता है, लेकिन यह संभव है।
dororpe

24

कोड Microsoft मध्यवर्ती भाषा में "संकलित" है, जो विधानसभा प्रारूप के समान है।

जब आप एक निष्पादन योग्य पर डबल-क्लिक करते हैं, तो विंडोज लोड होता है mscoree.dllजो फिर सीएलआर वातावरण सेट करता है और आपके प्रोग्राम का कोड शुरू करता है। JIT कंपाइलर आपके प्रोग्राम में MSIL कोड पढ़ना शुरू कर देता है और गतिशील रूप से कोड को x86 निर्देशों में संकलित करता है, जिसे CPU निष्पादित कर सकता है।


1

.NET MSIL नामक एक मध्यवर्ती भाषा का उपयोग करता है, जिसे कभी-कभी IL के रूप में संक्षिप्त किया जाता है। संकलक आपके स्रोत कोड को पढ़ता है और MSIL का उत्पादन करता है। जब आप प्रोग्राम चलाते हैं, तो .NET जस्ट इन टाइम (JIT) कंपाइलर आपके MSIL कोड को पढ़ता है और मेमोरी में एक निष्पादन योग्य एप्लिकेशन बनाता है। आपको इसमें से कोई भी दिखाई नहीं देगा, लेकिन यह जानने के लिए एक अच्छा विचार है कि पर्दे के पीछे क्या चल रहा है।


1

मैं उदाहरण के माध्यम से मूल सीपीयू निर्देशों में आईएल कोड को संकलित करने का वर्णन करूंगा।

public class Example 
{
    static void Main() 
    {
        Console.WriteLine("Hey IL!!!");
    }
}

मुख्य रूप से सीएलआर प्रकार के बारे में प्रत्येक विवरण जानता है और उस प्रकार से किस विधि को बुलाया जा रहा है, यह मेटाडेटा के कारण है।

जब सीएलआर उस समय देशी सीपीयू अनुदेश में आईएल निष्पादित करना शुरू कर देता है, तो सीएलआर मेन के कोड द्वारा संदर्भित हर प्रकार के आंतरिक डेटा संरचनाओं को आवंटित करता है।

हमारे मामले में हमारे पास केवल एक ही प्रकार का कंसोल है, सीएलआर उस आंतरिक संरचना के माध्यम से एक आंतरिक डेटा संरचना आवंटित करेगा, हम संदर्भित प्रकारों तक पहुंच प्राप्त करेंगे

उस डेटा संरचना के अंदर सीएलआर में उस प्रकार से परिभाषित सभी विधियों के बारे में प्रविष्टियां होती हैं। प्रत्येक प्रविष्टि उस पते को रखती है जहाँ विधि का कार्यान्वयन पाया जा सकता है।

जब इस संरचना को आरम्भ करते समय CLR प्रत्येक अनिर्दिष्ट FUNCTION में CLR के अंदर ही प्रत्येक प्रविष्टि को सेट करता है। और जैसा कि आप अनुमान लगा सकते हैं कि यह FUNCTION जिसे हम JIT कंपाइलर कहते हैं।

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

1.जब मेन के अपने पहले कॉल को राइटलाइन को JITCompiler फंक्शन कहते हैं।

2.JIT कंपाइलर फ़ंक्शन जानता है कि किस विधि को बुलाया जा रहा है और किस प्रकार इस पद्धति को परिभाषित करता है।

3. जब जेट कंपाइलर उस प्रकार को परिभाषित करता है, जो उस प्रकार को परिभाषित करता है और उस प्रकार से परिभाषित विधि के लिए आईएल कोड प्राप्त करता है, हमारे मामले में आईएल कोड ऑफ राइटलाइन विधि।

4.JIT संकलक डायनामिक मेमोरी ब्लॉक को आवंटित करता है, उसके बाद JIT सत्यापित करता है और IL कोड को मूल CPU कोड में संकलित करता है और उस मेमोरी ब्लॉक में CPU कोड सेव करता है।

5. जब JIT संकलक आंतरिक डेटा संरचना प्रविष्टि में वापस जाता है और पते को बदल देता है (जो मुख्य रूप से WriteLine के IL कोड कार्यान्वयन का संदर्भ देता है) पते के साथ नए गतिशील रूप से बनाए गए मेमोरी ब्लॉक जिसमें WriteLine के मूल CPU निर्देश होते हैं।

6. आमतौर पर, जेआईटी कंपाइलर फ़ंक्शन मेमोरी ब्लॉक में कोड के लिए कूदता है। यह कोड राइटलाइन विधि का कार्यान्वयन है।

7. लाइकलाइन के लागू होने के बाद, कोड Mains'code पर लौटता है जो निष्पादन को सामान्य रूप से जारी रखता है।


0

.NET फ्रेमवर्क MSIL (Microsoft मध्यवर्ती भाषा), जिसे IL भी कहा जाता है, का उत्पादन करने के लिए CLR पर्यावरण का उपयोग करता है। कंपाइलर आपके स्रोत कोड को पढ़ता है और जब आप अपनी परियोजना का निर्माण / संकलन करते हैं, तो यह MSIL उत्पन्न करता है। अब, जब आप अंत में अपना प्रोजेक्ट चलाते हैं, तो .NET .NET ( जस्ट-इन-टाइम कंपाइलर ) एक्शन में आता है। JIT आपके MSIL कोड को पढ़ता है और मूल कोड (जो x86 निर्देश हैं) का उत्पादन करता है जिसे CPU द्वारा आसानी से निष्पादित किया जा सकता है। JIT सभी MSIL निर्देशों को पढ़ता है और उन्हें Line by Line निष्पादित करता है।

यदि आप देखने में रुचि रखते हैं, तो पर्दे के पीछे क्या होता है, इसका उत्तर पहले ही दिया जा चुका है। कृपया अनुसरण करें - यहाँ

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