अंतर को समझना: पारंपरिक दुभाषिया, JIT संकलक, JIT दुभाषिया और AOT संकलक


130

मैं एक पारंपरिक दुभाषिया, एक JIT संकलक, एक JIT दुभाषिया और एक AOT संकलक के बीच के अंतरों को समझने की कोशिश कर रहा हूँ।

एक दुभाषिया सिर्फ एक मशीन (आभासी या भौतिक) है जो कुछ कंप्यूटर भाषा में निर्देशों को निष्पादित करता है। इस मायने में, जेवीएम एक दुभाषिया है और भौतिक सीपीयू दुभाषिए हैं।

समय-समय पर संकलन का अर्थ है कि कोड को किसी भाषा में निष्पादित करने (व्याख्या करने) से पहले संकलित करना।

हालाँकि मैं JIT कंपाइलर और JIT दुभाषिया की सटीक परिभाषाओं के बारे में निश्चित नहीं हूँ।

मेरे द्वारा पढ़ी गई परिभाषा के अनुसार, जेआईटी संकलन केवल व्याख्या करने से ठीक पहले कोड का संकलन कर रहा है।

तो मूल रूप से, JIT संकलन AOT संकलन है, जो निष्पादन (व्याख्या) से ठीक पहले किया गया है?

और एक जेआईटी दुभाषिया, एक ऐसा प्रोग्राम है जिसमें एक जेआईटी कंपाइलर और एक दुभाषिया दोनों शामिल हैं, और इसे लिखने से ठीक पहले कोड (जेआईटीज़) को संकलित करता है?

कृपया मतभेद स्पष्ट करें।


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

2
पर wikipages पढ़ें बस समय संकलन , AOT संकलक , संकलक , दुभाषिया , बाईटकोड और भी Queinnec की किताब छोटे टुकड़ों में लिस्प
बासिल Starynkevitch

जवाबों:


198

अवलोकन

भाषा X के लिए एक दुभाषिया एक प्रोग्राम (या मशीन, या सामान्य रूप से बस किसी प्रकार का तंत्र) है जो भाषा X में लिखे गए किसी भी प्रोग्राम p को निष्पादित करता है जैसे कि यह प्रभाव करता है और X के विनिर्देश द्वारा निर्धारित परिणामों का मूल्यांकन करता है । सीपीयू आमतौर पर अपने संबंधित निर्देशों के सेट के लिए व्याख्याकार होते हैं, हालांकि आधुनिक उच्च-प्रदर्शन कार्य केंद्र सीपीयू वास्तव में उससे अधिक जटिल हैं; उनके पास वास्तव में एक अंतर्निहित मालिकाना निजी अनुदेश सेट हो सकता है और या तो अनुवाद (संकलन) कर सकता है या बाहरी रूप से दृश्यमान सार्वजनिक अनुदेश सेट की व्याख्या कर सकता है।

एक संकलक से एक्स के लिए वाई एक प्रोग्राम (या एक मशीन, या सिर्फ सामान्य रूप में तंत्र के कुछ प्रकार) है कि किसी भी कार्यक्रम के लिए अनुवाद है पी कुछ भाषा से एक्स एक शब्दार्थ बराबर कार्यक्रम में पी ' कुछ भाषा में वाई इस तरह से है कि अर्थ विज्ञान कार्यक्रम संरक्षित हैं, यानी कि वाई के लिए एक दुभाषिया के साथ p, की व्याख्या करने से वही परिणाम प्राप्त होंगे और X के लिए दुभाषिया के साथ p की व्याख्या करने के समान प्रभाव होंगे । (ध्यान दें कि X और Y एक ही भाषा हो सकती है।)

मामले आगे के- समय (AOT) और जस्ट-इन-टाइम (JIT) का उल्लेख है जब संकलन जगह लेता है: "समय" उन शब्दों में निर्दिष्ट "क्रम", है यानी एक JIT कम्पाइलर प्रोग्राम को संकलित रूप में यह है चलने से पहले AOT कंपाइलर प्रोग्राम को कंपाइल करता है । ध्यान दें कि इसके लिए यह आवश्यक है कि भाषा X से भाषा Y तक JIT संकलक किसी तरह भाषा Y के लिए दुभाषिया के साथ मिलकर काम करेंअन्यथा, कार्यक्रम को चलाने का कोई तरीका नहीं होगा। (इसलिए, उदाहरण के लिए, एक JIT संकलक जो जावास्क्रिप्ट को x86 मशीन कोड के लिए संकलित करता है, एक x86 CPU के बिना कोई मतलब नहीं है; यह प्रोग्राम को चलाने के दौरान संकलित करता है, लेकिन x86 CPU के बिना यह प्रोग्राम चालू नहीं होगा।)

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

तो हमारे पास:

  • एओटी कंपाइलर: चलने से पहले कंपाइल करता है
  • JIT कंपाइलर: कंपाइल करते समय
  • दुभाषिया: चलाता है

जेआईटी कंपाइलर

जेआईटी संकलक के परिवार के भीतर, अभी भी कई अंतर हैं जैसे वे वास्तव में संकलित करते हैं, कितनी बार , और किस ग्रैन्युलैरिटी पर।

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

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

इंटरप्रेन्योर और कंपाइलर का मेल

दुभाषियों और संकलक को एकल भाषा निष्पादन इंजन में जोड़ा जा सकता है। दो विशिष्ट परिदृश्य हैं जहां यह किया जाता है।

से एक AOT संकलक का मेल एक्स के लिए वाई के लिए एक अनुवादक के साथ वाई । यहाँ, आमतौर पर X मनुष्यों द्वारा पठनीयता के लिए अनुकूलित कुछ उच्च-स्तरीय भाषा है, जबकि Yमशीनों द्वारा व्याख्या के लिए अनुकूलित एक कॉम्पैक्ट भाषा (अक्सर किसी प्रकार का बायटेकोड) है। उदाहरण के लिए, CPython Python निष्पादन इंजन में AOT कंपाइलर है जो Python sourcecode को CPython bytecode और एक दुभाषिया है जो CPython bytecode की व्याख्या करता है। इसी तरह, YARV रूबी के निष्पादन इंजन में AOT कंपाइलर है जो YARV bytecode को Ruby sourcecode और YARV bytecode की व्याख्या करने वाला दुभाषिया संकलित करता है। आप ऐसा क्यों करना चाहते हो? रूबी और पायथन दोनों बहुत उच्च-स्तरीय और कुछ हद तक जटिल भाषाएं हैं, इसलिए हम पहले उन्हें एक ऐसी भाषा में संकलित करते हैं जो पार्स करना आसान है और व्याख्या करना आसान है, और फिर उस भाषा की व्याख्या करें ।

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

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

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

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


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

1
@SebastianRedl, CPython से आप python -m compileall .एक बार मॉड्यूल चला या लोड कर सकते हैं । बाद के मामले में भी, चूंकि फाइलें बनी रहती हैं और पहले रन के बाद पुन: उपयोग की जाती हैं, ऐसा एओटी की तरह लगता है।
पॉल ड्रेपर

क्या आपके पास आगे पढ़ने के लिए कोई संदर्भ है? मैं V8 के बारे में अधिक जानना चाहता हूं।
विंस पानुकियो

@VincePanuccio पोस्ट का संदर्भ पूर्ण-कोडगेन और क्रैंकशाफ्ट संकलक से है जिन्हें तब से बदल दिया गया है । आप उनके बारे में ऑनलाइन पा सकते हैं।
eush77

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