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