compilation - एक जस्ट-इन-टाइम(जेआईटी) कंपाइलर क्या करता है?




compiler-construction jit (12)

JVM वास्तव में प्रदर्शन कारणों से रनटाइम के दौरान संकलन चरणों को निष्पादित करता है। इसका मतलब है कि जावा में एक साफ संकलन-निष्पादन अलगाव नहीं है। यह पहले जावा स्रोत कोड से बाइटकोड तक एक तथाकथित स्थैतिक संकलन करता है। फिर यह बाइटकोड निष्पादन के लिए JVM को पास कर दिया गया है। लेकिन बाइटकोड निष्पादित करना धीमा है इसलिए JVM मापता है कि कितनी बार बाइटकोड चलाया जाता है और जब यह बहुत अधिक बार चलाए जाने वाले कोड के "हॉटस्पॉट" का पता लगाता है तो यह "हॉटस्पॉट" कोड (हॉटस्पॉट प्रोफाइलर) के मशीनकोड में बाइटकोड से गतिशील संकलन करता है। तो प्रभावी ढंग से जावा प्रोग्राम मशीनकोड निष्पादन द्वारा चलाए जाते हैं।

एक जेआईटी कंपाइलर विशेष रूप से गैर-जेआईटी कंपाइलर के विरोध में क्या करता है? क्या कोई विवरण संक्षिप्त और समझने में आसान हो सकता है?


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


जस्ट-इन-टाइम (जेआईटी) संकलन, (गतिशील अनुवाद या रन-टाइम संकलन), कंप्यूटर कोड को निष्पादित करने का एक तरीका है जिसमें निष्पादन से पहले - रन के समय - प्रोग्राम के निष्पादन के दौरान संकलन शामिल होता है

आईटी संकलन मशीन कोड के अनुवाद के लिए दो पारंपरिक दृष्टिकोणों का संयोजन है - अग्रिम-समय-समय संकलन (एओटी) , और व्याख्या - और दोनों के कुछ फायदे और दोषों को जोड़ती है। जेआईटी संकलन संकलन की लचीलापन के साथ संकलित कोड की गति को जोड़ती है

चलिए जेआईटी में जेवीएम में इस्तेमाल करते हैं,

उदाहरण के लिए, हॉटस्पॉट जेवीएम जेआईटी कंपाइलर गतिशील अनुकूलन उत्पन्न करते हैं। दूसरे शब्दों में, वे जावा एप्लिकेशन चल रहे हैं और अंतर्निहित सिस्टम आर्किटेक्चर के लिए लक्षित उच्च निष्पादित देशी मशीन निर्देश उत्पन्न करते समय ऑप्टिमाइज़ेशन निर्णय लेते हैं

जब संकलन के लिए कोई विधि चुना जाता है, तो JVM अपने बाइटकोड को जस्ट-इन-टाइम कंपाइलर (जेआईटी) में खिलाता है। जेआईटी को विधि को संकलित करने से पहले बाइटकोड के अर्थशास्त्र और वाक्यविन्यास को समझने की आवश्यकता है। जेआईटी कंपाइलर को विधि का विश्लेषण करने में मदद करने के लिए, इसके बाइटकोड को पहली बार ट्रेस पेड़ नामक आंतरिक प्रतिनिधित्व में सुधार किया जाता है, जो मशीन कोड को बाइटकोड से अधिक बारीकी से दिखता है। विश्लेषण और अनुकूलन तब विधि के पेड़ पर किए जाते हैं। अंत में, पेड़ों का मूल कोड में अनुवाद किया जाता है।

एक ट्रेस पेड़ एक डेटा संरचना है जिसका प्रयोग प्रोग्रामिंग कोड के रनटाइम संकलन में किया जाता है। ट्रेस पेड़ का उपयोग 'बस समय संकलक' के प्रकार में किया जाता है जो हॉटस्पॉट के दौरान कोड निष्पादित करता है और इसे संकलित करता है। इसे देखें।

संदर्भ लें:


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

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

Source


जेआईटी जस्ट-इन-टाइम के लिए खड़ा है जिसका मतलब है कि कोड की आवश्यकता होने पर संकलित हो जाती है, रनटाइम से पहले नहीं।

यह फायदेमंद है क्योंकि संकलक कोड उत्पन्न कर सकता है जो आपकी विशेष मशीन के लिए अनुकूलित है। आपके स्थिर सी कंपाइलर की तरह एक स्थिर कंपाइलर, डेवलपर की मशीन पर निष्पादन योग्य कोड पर सभी कोड संकलित करेगा। इसलिए संकलक कुछ मान्यताओं के आधार पर अनुकूलन करेगा। यह अधिक धीरे-धीरे संकलित कर सकता है और अधिक अनुकूलन कर सकता है क्योंकि यह उपयोगकर्ता के लिए प्रोग्राम के निष्पादन को धीमा नहीं कर रहा है।


जेआईटी-बस समय में जब शब्द की आवश्यकता होती है (मांग पर)

विशिष्ट परिदृश्य:

स्रोत कोड पूरी तरह से मशीन कोड में परिवर्तित हो गया है

जेआईटी परिदृश्य:

स्रोत कोड को असेंबली भाषा में परिवर्तित किया जाएगा [सीएल के लिए पूर्व आईएल (इंटरमीडिएट भाषा) के लिए, जावा के लिए बाइटकोड]।

इंटरमीडिएट कोड केवल मशीन भाषा में परिवर्तित हो जाता है जब आवेदन की आवश्यकता होती है, आवश्यक कोड केवल कोड कोड में परिवर्तित होते हैं।

जेआईटी बनाम गैर-जेआईटी तुलना:

  • जेआईटी में सभी कोड को मशीन कोड में परिवर्तित नहीं किया जाता है, पहले जरूरी कोड का एक हिस्सा मशीन कोड में परिवर्तित हो जाएगा, यदि मशीन में कोई विधि या कार्यक्षमता नहीं है तो उसे मशीन कोड में बदल दिया जाएगा ... यह कम हो जाता है सीपीयू पर बोझ।

  • चूंकि मशीन कोड रन टाइम पर जेनरेट किया जाएगा .... जेआईटी कंपाइलर मशीन कोड का उत्पादन करेगा जो मशीन के सीपीयू आर्किटेक्चर को चलाने के लिए अनुकूलित किया गया है।

जेआईटी उदाहरण:

  1. जावा जेआईटी में जेवीएम (जावा वर्चुअल मशीन) में है
  2. सी # में यह सीएलआर (सामान्य भाषा रनटाइम) में है
  3. एंड्रॉइड में यह नए संस्करणों में डीवीएम (डाल्विक वर्चुअल मशीन), या एआरटी (एंड्रॉइड रनटाइम) में है।

जैसा कि अन्य ने उल्लेख किया है

जेआईटी जस्ट-इन-टाइम के लिए खड़ा है जिसका मतलब है कि कोड की आवश्यकता होने पर संकलित हो जाती है, रनटाइम से पहले नहीं।

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

अगली बार जब इस फ़ंक्शन की गणना की जाती है तो उसी संकलित कोड को फिर से सामान्य व्याख्या के विपरीत निष्पादित किया जाता है जिसमें कोड को लाइन से फिर से परिभाषित किया जाता है। यह निष्पादन तेजी से बनाता है।


निम्नलिखित कोड उदाहरण दिखाते हैं कि जेआईटी जावा कोड को कैसे अनुकूलित करता है।

अनुकूलन से पहले कोड

    class A {
      B b;
      public void newMethod() {
        y = b.get();
        ...do stuff...
        z = b.get();
        sum = y + z;
      }
    }

class B {
   int value;
   final int get() {
      return value;
   }
}

अनुकूलन के बाद कोड

class A {
B b;
public void newMethod() {
   y = b.value;
   ...do stuff...
   sum = y + y;
}
}
class B {
   int value;
   final int get() {
      return value;
   }
}

मूल रूप से, कोड में b.get () विधि में दो कॉल शामिल थे। ऑप्टिमाइज़ेशन के बाद, दो विधि कॉल को एक वैरिएबल-कॉपी ऑपरेशन में अनुकूलित किया जाता है; अर्थात, अनुकूलित कोड को कक्षा बी के फील्ड वैल्यू को प्राप्त करने के लिए विधि कॉल करने की आवश्यकता नहीं है।


बाइट कोड (जो आर्किटेक्चर तटस्थ है) के बाद जावा कंपाइलर द्वारा उत्पन्न किया गया है, निष्पादन JVM (जावा में) द्वारा संभाला जाएगा। बाइट कोड लोडर द्वारा JVM में लोड किया जाएगा और फिर प्रत्येक बाइट निर्देश का अर्थ है।

जब हमें कई बार एक विधि कॉल करने की आवश्यकता होती है, तो हमें कई बार एक ही कोड की व्याख्या करने की आवश्यकता होती है और इसमें आवश्यकतानुसार अधिक समय लग सकता है। तो हमारे पास जेआईटी (बस-इन-टाइम) कंपाइलर्स हैं। जब बाइट को JVM (इसके रन टाइम) में लोड किया गया है, तो संपूर्ण कोड को संकलित करने के बजाय संकलित किया जाएगा, इस प्रकार समय बचाएगा।

जेआईटी कंपाइलर केवल रन टाइम के दौरान काम करता है, इसलिए हमारे पास कोई बाइनरी आउटपुट नहीं है।


बाइट कोड का 20% समय का 80% उपयोग किया जाता है। जेआईटी कंपाइलर इन आंकड़ों को प्राप्त करता है और इन 20% बाइट कोड को इनलाइन विधियों को जोड़कर, अप्रयुक्त ताले आदि को हटाकर और उस मशीन के लिए विशिष्ट बाइटकोड बनाकर तेज़ी से चलाने के लिए अनुकूलित करता है। मैं इस लेख से उद्धृत हूं, मैंने पाया कि यह आसान था। http://java.dzone.com/articles/just-time-compiler-jit-hotspot


शुरुआत में, एक संकलक ऑब्जेक्ट कोड (मशीन निर्देश) में एक उच्च स्तरीय भाषा (असेंबलर से उच्च स्तर के रूप में परिभाषित) को बदलने के लिए ज़िम्मेदार था, जिसे तब एक लिंक करने वाले (एक लिंकर द्वारा) निष्पादित करने योग्य में जोड़ा जाएगा।

भाषाओं के विकास में एक बिंदु पर, कंपाइलर्स एक उच्च स्तरीय भाषा को छद्म कोड में संकलित करेंगे, जिसे आपके प्रोग्राम को चलाने के लिए (दुभाषिया द्वारा) का अर्थ दिया जाएगा। इसने ऑब्जेक्ट कोड और एक्जिक्यूटिव को हटा दिया, और इन भाषाओं को कई ऑपरेटिंग सिस्टम और हार्डवेयर प्लेटफ़ॉर्म पर पोर्टेबल होने की अनुमति दी। पास्कल (जो पी-कोड के लिए संकलित) पहले में से एक था; जावा और सी # हाल के उदाहरण हैं। आखिर में शब्द पी-कोड को बाइटकोड के साथ बदल दिया गया था, क्योंकि अधिकांश छद्म-संचालन एक बाइट लंबे होते हैं।

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


बस समय संकलक (जेआईटी) में:
यह जावा बाइटकोड को उस विशिष्ट सीपीयू के मशीन निर्देशों में संकलित करता है।

उदाहरण के लिए, यदि हमारे जावा कोड में लूप स्टेटमेंट है:

while(i<10){
    // ...
    a=a+i;
    // ...
 }

यदि ऊपर का मान 0 है तो उपरोक्त लूप कोड 10 गुना चलता है।

बाइटकोड को 10 बार बार-बार संकलित करना जरूरी नहीं है क्योंकि एक ही निर्देश 10 गुना निष्पादित करने जा रहा है। उस स्थिति में, केवल उस कोड को संकलित करना आवश्यक है और आवश्यक संख्या के लिए मूल्य बदला जा सकता है। तो, जस्ट इन टाइम (जेआईटी) कंपाइलर ऐसे बयान और विधियों का ट्रैक रखता है (जैसा कि पहले बताया गया है) और बाइट कोड के ऐसे टुकड़ों को बेहतर प्रदर्शन के लिए मशीन कोड में संकलित करता है।

एक और समान उदाहरण यह है कि तारों / वाक्यों की सूची में "नियमित अभिव्यक्ति" का उपयोग करके पैटर्न की खोज।

जेआईटी कंपाइलर सभी कोड को कोड कोड में संकलित नहीं करता है। यह उस कोड को संकलित करता है जिसमें रन टाइम पर समान पैटर्न होता है।

अधिक पढ़ने के लिए जेआईटी को समझने के लिए इस ओरेकल दस्तावेज को देखें।