क्या संकलनकर्ता तेजी से संकलन समय के लिए मल्टीथ्रेडिंग का उपयोग करते हैं?


16

यदि मुझे अपने संकलक पाठ्यक्रम को सही ढंग से याद है, तो विशिष्ट संकलक में निम्नलिखित सरलीकृत रूपरेखा है:

  • स्रोत कोड चरित्र-दर-वर्ण एक लेक्सिकल विश्लेषक स्कैन (या कुछ स्कैनिंग फ़ंक्शन को कॉल करता है)
  • वैधता के लिए lexemes के शब्दकोश के खिलाफ इनपुट वर्णों की स्ट्रिंग की जाँच की जाती है
  • यदि लेक्मे मान्य है, तो इसे उस टोकन के रूप में वर्गीकृत किया जाता है, जिससे यह मेल खाता है
  • पार्सर टोकन के संयोजन के सिंटैक्स को मान्य करता है; टोकन-टू-टोकन

क्या सैद्धांतिक रूप से स्रोत कोड को क्वार्टर (या जो भी हर) में विभाजित करना और स्कैनिंग और पार्स प्रक्रिया को गुणा करना संभव है? क्या संकलक मौजूद हैं जो मल्टीथ्रेडिंग का उपयोग करते हैं?




1
@RobertHarvey पहले लिंक के शीर्ष उत्तर ने लिखा, "लेकिन कंपाइलर अभी भी एकल-थ्रेडेड हैं।" तो यह एक नहीं है?
8protons

मेरा सुझाव है कि आप शेष उत्तर, विशेष रूप से यह एक , और दूसरा लिंक जो मैंने पोस्ट किया है, उसे पढ़ें ।
रॉबर्ट हार्वे

2
@RobertHarvey दूसरा लिंक जो आपने पोस्ट किया है, मेरी समझ से कि यह क्या कह रहा है, एक संकलक के बारे में बात कर रहा है जो आपके संकलित एप्लिकेशन का एक मल्टीथ्रेडेड संस्करण उत्पन्न करता है। यह संकलक के बारे में ही नहीं है। आपके साझा संसाधनों और प्रतिक्रिया देने के लिए समय निकालने के लिए धन्यवाद।
8protons

जवाबों:


29

बड़े सॉफ्टवेयर प्रोजेक्ट आमतौर पर कई संकलन इकाइयों से बने होते हैं जिन्हें अपेक्षाकृत स्वतंत्र रूप से संकलित किया जा सकता है, और इसलिए संकलन को अक्सर समानांतर में कई बार संकलित करके एक बहुत ही मोटे ग्रैन्युलैरिटी में समानांतर किया जाता है। यह ओएस प्रक्रियाओं के स्तर पर होता है और संकलक के बजाय निर्माण प्रणाली द्वारा समन्वित होता है। मुझे लगता है कि यह आपने पूछा नहीं है, लेकिन यह है कि सबसे अधिक संकलक में समानांतर करने के लिए निकटतम बात है।

ऐसा क्यों है? अच्छी तरह से, संकलक जो काम करते हैं, उनमें से ज्यादातर खुद को आसानी से समानांतर करने के लिए उधार नहीं देते हैं:

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

इसके बाद, यह थोड़ा आसान हो जाता है। प्रकार की जाँच और अनुकूलन और कोड पीढ़ी, सिद्धांत रूप में, फ़ंक्शन ग्रैन्युलैरिटी में समानांतर हो सकती है। मुझे अभी भी कुछ पता है अगर कोई कंपाइलर ऐसा कर रहा है, शायद इसलिए किसी भी कार्य को बड़े पैमाने पर करना काफी चुनौतीपूर्ण है। आपको यह भी विचार करना होगा कि अधिकांश बड़ी सॉफ्टवेयर परियोजनाओं में इतनी सारी संकलन इकाइयाँ होती हैं जो "समानांतर रूप से कंपाइलरों का एक गुच्छा चलाती हैं" दृष्टिकोण पूरी तरह से आपके सभी कोर को कब्जे में रखने के लिए पर्याप्त है (और कुछ मामलों में, यहां तक ​​कि एक संपूर्ण सर्वर फ़ार्म)। साथ ही, बड़े संकलन कार्यों में डिस्क I / O उतने ही अड़चन हो सकते हैं जितने संकलन के वास्तविक कार्य।

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

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

2

संकलन एक "शर्मनाक समानांतर" समस्या है।

किसी एक फाइल को संकलित करने के लिए समय की परवाह नहीं है। लोग 1000 फाइलों के संकलन के समय की परवाह करते हैं। और 1000 फाइलों के लिए, प्रोसेसर का प्रत्येक कोर एक बार में एक फाइल को खुशी से संकलित कर सकता है, सभी कोर को पूरी तरह से व्यस्त रखते हुए।

युक्ति: यदि आप इसे सही कमांड लाइन विकल्प देते हैं तो "कर" कई कोर का उपयोग करता है। इसके बिना यह 16 कोर सिस्टम पर एक के बाद एक फाइल संकलित करेगा। इसका मतलब है कि आप इसे अपने बिल्ड विकल्पों में एक पंक्ति परिवर्तन के साथ 16 गुना तेजी से संकलित कर सकते हैं।

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