paint-brush
द रियल सी++ किलर (नॉट यू, रस्ट)द्वारा@oleksandrkaleniuk
50,726 रीडिंग
50,726 रीडिंग

द रियल सी++ किलर (नॉट यू, रस्ट)

द्वारा Oleksandr Kaleniuk17m2023/02/14
Read on Terminal Reader

बहुत लंबा; पढ़ने के लिए

खराब प्रोग्रामर के साथ अच्छा कोड लिखना XX सदी की समस्या है। अब हमें और भी बेहतर कोड की आवश्यकता है लेकिन अच्छे प्रोग्रामर द्वारा लिखा गया है, एक कार्य जिसे कोई वर्तमान C++ किलर संबोधित नहीं कर रहा है। वास्तविक क्रांति संकलकों से परे है।
featured image - द रियल सी++ किलर (नॉट यू, रस्ट)
Oleksandr Kaleniuk HackerNoon profile picture


नमस्ते! मैं ऑलेक्ज़ेंडर कालेनियुक हूं और मैं सी++ हॉलिक हूं। मैं 17 सालों से C++ में लिख रहा हूं और उन सभी 17 सालों से मैं इस विनाशकारी लत से छुटकारा पाने की कोशिश कर रहा हूं।


यह सब 2005 में एक 3D स्पेस सिम्युलेटर इंजन के साथ शुरू हुआ था। इंजन में वह सब कुछ था जो 2005 में C++ में था। थ्री-स्टार पॉइंटर्स, डिपेंडेंसी की आठ परतें, और हर जगह C-स्टाइल मैक्रोज़। असेंबली बिट्स भी थे। Iterators Stepanov-शैली और मेटा-कोड अलेक्जेंड्रेस्कु-शैली। कोड में सब कुछ था। बेशक, सबसे महत्वपूर्ण प्रश्न के उत्तर को छोड़कर: क्यों?


थोड़ी देर में इस सवाल का जवाब भी मिल गया। सिर्फ "किस लिए" के रूप में नहीं बल्कि "कैसे" के रूप में। जैसा कि यह निकला, इंजन को 5 अलग-अलग टीमों द्वारा लगभग 8 वर्षों के लिए लिखा गया है। और हर टीम अपने पसंदीदा सनक को पुराने कोड को नए स्टाइल वाले रैपर में लपेटकर परियोजना में ले आई और ऐसा करते समय केवल 10-20 माइक्रोकार्मैक की कार्यक्षमता जोड़ती है।


सबसे पहले, मैं ईमानदारी से हर छोटी चीज़ को टटोलने की कोशिश कर रहा था। यह एक संतुष्टिदायक अनुभव नहीं था, बिल्कुल नहीं, और किसी बिंदु पर, मैंने हार मान ली। मैं अभी भी कार्यों को बंद कर रहा था, और बग्स को ठीक कर रहा था। यह नहीं कह सकता कि मैं बहुत उत्पादक था, लेकिन निकाल दिए जाने के लिए पर्याप्त नहीं था। लेकिन फिर मेरे बॉस ने मुझसे पूछा: "क्या आप असेंबली से GLSG में कुछ शेडर कोड फिर से लिखना चाहते हैं?" मैंने सोचा कि भगवान जानता है कि यह जीएलएसएल कैसा दिखता है लेकिन यह संभवतः सी ++ से भी बदतर नहीं हो सकता है और हाँ कहा। यह बदतर नहीं था।


और इस तरह का एक पैटर्न बन गया। मैं अभी भी ज्यादातर सी ++ में लिख रहा था लेकिन हर बार किसी ने मुझसे पूछा "क्या आप उस गैर-सी ++ चीज़ को करना चाहते हैं?" मुझे यकीन था!" और मैंने वह काम किया जो कुछ भी था। मैंने C89, MASM32, C#, PHP, डेल्फी, एक्शनस्क्रिप्ट, जावास्क्रिप्ट, एरलांग, पायथन, हास्केल, डी, रस्ट, और यहां तक कि अपमानजनक रूप से खराब इंस्टॉलशील्ड स्क्रिप्टिंग भाषा में लिखा था। मैंने VisualBasic में, बैश में, और कुछ मालिकाना भाषाओं में लिखा, मैं कानूनी तौर पर बात भी नहीं कर सकता। मैंने गलती से खुद भी एक बना लिया। मैंने गेम डिजाइनरों को संसाधन लोडिंग को स्वचालित करने में मदद करने के लिए एक साधारण लिस्प-शैली का दुभाषिया बनाया और छुट्टी पर चला गया। जब मैं वापस आया, तो वे इस दुभाषिया में पूरे खेल के दृश्य लिख रहे थे, इसलिए हमें कम से कम परियोजना के अंत तक इसका समर्थन करना था।


तो पिछले 17 सालों से, मैं ईमानदारी से C++ को छोड़ने की कोशिश कर रहा था, लेकिन हर बार, एक नई चमकदार चीज की कोशिश करने के बाद, मैं वापस आ रहा था। फिर भी, मुझे लगता है कि C++ में लिखना एक बुरी आदत है। यह असुरक्षित है, जितना प्रभावी माना जाता है उतना प्रभावी नहीं है, और यह प्रोग्रामर की मानसिक क्षमता की भयानक मात्रा को उन चीजों पर बर्बाद कर देता है जिनका सॉफ्टवेयर बनाने से कोई लेना-देना नहीं है। क्या आप जानते हैं कि एमएसवीसी uint16_t(50000) + uin16_t(50000) == -1794967296 में? आप जानते हैं क्यों? हां मैंने भी यही सोचा था।


मेरा मानना है कि युवा पीढ़ी को सी ++ को अपना पेशा बनाने से हतोत्साहित करने के लिए लंबे समय तक सी ++ प्रोग्रामर की नैतिक जिम्मेदारी है क्योंकि यह शराबियों की नैतिक जिम्मेदारी है जो युवाओं को खतरे के बारे में चेतावनी देने के लिए नहीं छोड़ सकते हैं।


लेकिन मैं क्यों नहीं छोड़ सकता? क्या बात क्या बात? मामला यह है कि कोई भी भाषा, विशेष रूप से तथाकथित "C++ किलर" आधुनिक दुनिया में C++ पर कोई वास्तविक लाभ नहीं देती है। उन सभी नई भाषाओं में ज्यादातर प्रोग्रामर को अपने स्वयं के अच्छे के लिए पट्टे पर रखने पर ध्यान केंद्रित किया जाता है। यह ठीक है, सिवाय इसके कि खराब प्रोग्रामर के साथ अच्छा कोड लिखना XX सदी की एक समस्या है जब ट्रांजिस्टर हर 18 महीने में दो गुना बढ़ जाते थे, और प्रोग्रामर की संख्या हर 5 साल में दोगुनी हो जाती थी।


हम 2023 में जी रहे हैं। हमारे पास इतिहास में पहले से कहीं अधिक अनुभवी प्रोग्रामर हैं। और हमें कुशल सॉफ़्टवेयर की आवश्यकता पहले से कहीं अधिक है।


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


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


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


और अचानक यह पता चलता है कि सभी "सी ++ हत्यारे", यहां तक कि जिन्हें मैं पूरे दिल से प्यार करता हूं और रस्ट, जूलिया और डी की तरह सम्मान करता हूं, वे XXI सदी की समस्या का समाधान नहीं करते हैं। वे अभी भी एक्सएक्स में फंस गए हैं। वे आपको कम बग के साथ अधिक फीचर लिखने में मदद करते हैं, लेकिन जब आप किराए पर लेने वाले हार्डवेयर से आखिरी फ्लॉप को निचोड़ना चाहते हैं तो वे ज्यादा मददगार नहीं होते हैं।


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


तो, कौन सी प्रौद्योगिकियां आपको सी ++ पर प्रतिस्पर्धात्मक लाभ देती हैं या आम तौर पर बोलती हैं, सभी पारंपरिक समय-समय पर संकलक? अच्छा प्रश्न। खुशी है कि आपने पूछा।


सी ++ हत्यारा नंबर 1। सर्पिल

लेकिन इससे पहले कि हम स्पाइरल के साथ आगे बढ़ें, आइए देखें कि आपका अंतर्ज्ञान कितनी अच्छी तरह काम करता है। आपको क्या लगता है कि कौन तेज है: एक मानक सी ++ साइन फ़ंक्शन, या साइन का 4-टुकड़ा बहुपद मॉडल?


 auto y = std::sin(x); // vs. y = -0.000182690409228785*x*x*x*x*x*x*x +0.00830460224186793*x*x*x*x*x -0.166651012143690*x*x*x +x;


अगला सवाल। शॉर्ट सर्किटिंग के साथ लॉजिकल ऑपरेशंस का उपयोग करके, या इससे बचने के लिए एक कंपाइलर को ट्रिक करने और लॉजिकल एक्सप्रेशन को थोक में गणना करने के लिए तेजी से क्या काम करता है?


 if (xs[i] == 1 && xs[i+1] == 1 && xs[i+2] == 1 && xs[i+3] == 1) // xs are bools stored as ints // vs. inline int sq(int x) { return x*x; } if(sq(xs[i] - 1) + sq(xs[i+1] - 1) + sq(xs[i+2] - 1) + sq(xs[i+3] - 1) == 0)


एक और। किस तरह का ट्रिपल तेजी से होता है: स्वैप-सॉर्ट या इंडेक्स-सॉर्ट?


 if(s[0] > s[1]) swap(s[0], s[1]); if(s[1] > s[2]) swap(s[1], s[2]); if(s[0] > s[1]) swap(s[0], s[1]); // vs. const auto a = s[0]; const auto b = s[1]; const auto c = s[2]; s[int(a > b) + int(a > c)] = a; s[int(b >= a) + int(b > c)] = b; s[int(c >= a) + int(c >= b)] = c;


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


कोड किस CPU या GPU को लक्षित करता है? कौन सा कंपाइलर कोड बनाने वाला है? कौन से कंपाइलर ऑप्टिमाइज़ेशन चालू हैं और कौन से बंद हैं? आप केवल तभी भविष्यवाणी करना शुरू कर सकते हैं जब आप यह सब जानते हों, या बेहतर अभी तक, प्रत्येक विशेष समाधान के लिए रन टाइम को मापना।


  1. -O2 -march=native के साथ क्लैंग 11 के साथ बनाया गया हो और Intel Core i7-9700F पर चलता हो तो एक बहुपद मॉडल मानक साइन से 3 गुना तेज होता है। लेकिन अगर nvcc के साथ --use-fast-math और GPU के साथ GeForce GTX 1050 Ti Mobile बनाया जाता है, तो मानक साइन मॉडल की तुलना में 10 गुना तेज है।


  2. सदिश अंकगणित के लिए शॉर्ट-सर्कुलेटेड लॉजिक का व्यापार i7 पर भी समझ में आता है। स्निपेट को दोगुनी तेज़ी से काम करने देता है। लेकिन ARMv7 पर एक ही क्लैंग और -O2 के साथ, माइक्रो-ऑप्टिमाइज़ेशन की तुलना में मानक तर्क 25% तेज है।


  3. और इंडेक्स-सॉर्ट बनाम स्वैप-सॉर्ट के साथ, इंडेक्स-सॉर्ट इंटेल पर 3 गुना तेज है, और GeForce पर स्वैप-सॉर्ट 3 गुना तेज है।


तो प्रिय माइक्रो-ऑप्टिमाइज़ेशन हम सभी को बहुत पसंद हैं, दोनों हमारे कोड को कारक 3 से गति दे सकते हैं, और इसे 90% धीमा कर सकते हैं। यह सब संदर्भ पर निर्भर करता है। यह कितना अद्भुत होगा यदि एक कंपाइलर हमारे लिए सबसे अच्छा विकल्प चुन सकता है, उदाहरण के लिए जब हम बिल्ड लक्ष्य को स्विच करते हैं तो इंडेक्स-सॉर्ट चमत्कारिक रूप से स्वैप-सॉर्ट में बदल जाएगा। लेकिन ऐसा नहीं हो सका।


  1. यहां तक कि अगर हम गति के लिए सटीक व्यापार करने के लिए संकलक को एक बहुपद मॉडल के रूप में साइन को फिर से लागू करने की अनुमति देते हैं, तब भी यह हमारे लक्ष्य सटीकता को नहीं जानता है। सी ++ में, हम यह नहीं कह सकते कि "इस फ़ंक्शन को उस त्रुटि की अनुमति है"। हमारे पास केवल "--उपयोग-फास्ट-गणित" जैसे संकलक झंडे हैं और केवल एक अनुवाद इकाई के दायरे में हैं।


  2. दूसरे उदाहरण में, संकलक यह नहीं जानता है कि हमारे मान 0 या 1 तक सीमित हैं और संभवतः हम जो अनुकूलन कर सकते हैं उसका प्रस्ताव नहीं दे सकते। हम शायद एक उचित बूल प्रकार का उपयोग करके इसका संकेत दे सकते थे लेकिन यह एक पूरी तरह से अलग समस्या होती।


  3. और तीसरे उदाहरण में, कोड के टुकड़े पर्यायवाची के रूप में पहचाने जाने के लिए बहुत अलग हैं। हमने कोड को बहुत अधिक विस्तृत किया है। यदि यह सिर्फ std :: सॉर्ट होता, तो यह पहले से ही कंपाइलर को एल्गोरिथम चुनने की अधिक स्वतंत्रता देता। लेकिन इसने या तो इंडेक्स-सॉर्ट नहीं स्वैप सॉर्ट चुना होगा क्योंकि वे दोनों बड़े सरणियों पर अक्षम हैं और std::sort एक सामान्य चलने योग्य कंटेनर के साथ काम करता है।


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


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


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




सर्पिल एक शोध परियोजना है। यह दायरे और बजट में सीमित है। लेकिन इसके परिणाम पहले से ही प्रभावशाली हैं। तेजी से फूरियर रूपांतरण पर, उनका समाधान एमकेएल और एफएफटीडब्ल्यू कार्यान्वयन दोनों को निर्णायक रूप से बेहतर बनाता है। उनका कोड ~ 2x तेज है। इंटेल पर भी।


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


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


सी ++ हत्यारा संख्या 2. नुम्बा

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


"कुछ और" पायथन प्रतीत हुआ। 90 के दशक में एक भाषा को किसी ने गंभीरता से नहीं लिया क्योंकि यह एक और स्क्रिप्टिंग भाषा थी जो हमारे पास पहले से ही काफी थी।



कोई कहेगा: "बाह, पायथन धीमा है", और एक मूर्ख की तरह दिखेगा क्योंकि यह पारिभाषिक बकवास है। अकॉर्डियन या फ्राइंग पैन की तरह, एक भाषा केवल तेज या धीमी नहीं हो सकती। जैसे एक अकॉर्डियन की गति इस बात पर निर्भर करती है कि कौन खेल रहा है, किसी भाषा की "गति" इस बात पर निर्भर करती है कि उसका कंपाइलर कितना तेज़ है।


"लेकिन पायथन एक संकलित भाषा नहीं है" कोई जारी रख सकता है, और एक बार फिर मिसफायर कर सकता है। बहुत सारे पायथन कंपाइलर हैं और उनमें से सबसे आशाजनक इसके बदले में एक पायथन स्क्रिप्ट है। मुझे समझाने दो।


मेरे पास एक बार एक प्रोजेक्ट था। एक 3डी-प्रिंटिंग सिमुलेशन जो मूल रूप से पायथन में लिखा गया था और फिर "प्रदर्शन के लिए" सी ++ में फिर से लिखा गया था, और फिर जीपीयू में पोर्ट किया गया था, जो कि मेरे आने से पहले था। फिर मैंने जीपीयू कोड को अनुकूलित करने के लिए बिल्ड को लिनक्स में पोर्ट करने में महीनों बिताए। Tesla M60 चूंकि यह उस समय AWS में सबसे सस्ता था, और Python में मूल कोड के साथ जाने के लिए C++/CU कोड में सभी परिवर्तनों को मान्य करता था। इसलिए मैंने सब कुछ किया, सिवाय उन चीजों के जिन्हें मैं सामान्य रूप से ज्यामितीय एल्गोरिदम तैयार करने में माहिर हूं।


और जब मेरे पास आखिरकार सब कुछ काम कर गया, तो ब्रेमेन के एक छात्र ने मुझे फोन किया और पूछा: "तो आप विषम सामान में अच्छे हैं, क्या आप मुझे जीपीयू पर एक एल्गोरिदम चलाने में मदद कर सकते हैं?" बिल्कुल! मैंने उसे CUDA, CMake, Linux निर्माण, परीक्षण और अनुकूलन के बारे में बताया; शायद एक घंटा बात करते हुए बिताया। उन्होंने वह सब बहुत विनम्रता से सुना, लेकिन अंत में कहा: "यह सब बहुत दिलचस्प है, लेकिन मेरा एक बहुत विशिष्ट प्रश्न है। तो मेरे पास एक फ़ंक्शन है, मैंने इसकी परिभाषा से पहले @cuda.jit लिखा था, और पायथन सरणियों के बारे में कुछ कहता है और कर्नेल को संकलित नहीं करता है। क्या आप जानते हैं कि यहाँ क्या समस्या हो सकती है?"


मुझे नहीं पता था। उसने एक दिन में खुद इसका पता लगा लिया। जाहिरा तौर पर, Numba देशी पायथन सूचियों के साथ काम नहीं करता है, यह केवल NumPy सरणियों में डेटा स्वीकार करता है। तो उन्होंने इसे समझ लिया और जीपीयू पर अपना एल्गोरिदम चलाया। पायथन में। उनके पास कोई समस्या नहीं थी जिस पर मैंने महीनों बिताए। क्या आप इसे लिनक्स पर चाहते हैं? कोई समस्या नहीं है, बस इसे Linux पर चलाएँ। क्या आप चाहते हैं कि यह पायथन कोड के अनुरूप हो? कोई समस्या नहीं, यह पायथन कोड है। क्या आप लक्षित प्लेटफॉर्म के लिए अनुकूलन करना चाहते हैं? फिर कोई समस्या नहीं। Numba उस प्लेटफ़ॉर्म के लिए कोड का अनुकूलन करेगा जिस पर आप कोड चलाते हैं क्योंकि यह समय से पहले संकलित नहीं होता है, यह पहले से ही तैनात किए जाने पर मांग पर संकलित करता है।


क्या यह कमाल नहीं है? अच्छा नहीं। वैसे भी मेरे लिए नहीं। मैंने C++ समस्याओं को हल करने में महीनों बिताए जो Numba में कभी नहीं होते, और ब्रेमेन के एक पार्ट-टाइमर ने कुछ दिनों में वही काम किया। अगर यह Numba के साथ उनका पहला अनुभव नहीं होता तो इसमें कुछ घंटे लग सकते थे। तो यह नुम्बा क्या है? यह किस प्रकार का जादू है?


कोई जादू टोना नहीं। पायथन सज्जाकार कोड के हर टुकड़े को आपके लिए अपने सार सिंटैक्स ट्री में बदल देते हैं, इसलिए आप इसके साथ जो चाहें कर सकते हैं। Numba एक Python लाइब्रेरी है जो सार सिंटैक्स ट्री को किसी भी बैकएंड के साथ संकलित करना चाहती है और किसी भी प्लेटफॉर्म के लिए इसका समर्थन करती है। यदि आप अपने पायथन कोड को बड़े पैमाने पर समानांतर फैशन में सीपीयू कोर पर चलाने के लिए संकलित करना चाहते हैं - तो बस नंबा को इसे संकलित करने के लिए कहें। यदि आप जीपीयू पर कुछ चलाना चाहते हैं, तो आपको केवल पूछना चाहिए


 @cuda.jit def matmul(A, B, C): """Perform square matrix multiplication of C = A * B.""" i, j = cuda.grid(2) if i < C.shape[0] and j < C.shape[1]: tmp = 0. for k in range(A.shape[1]): tmp += A[i, k] * B[k, j] C[i, j] = tmp


Numba Python कंपाइलर्स में से एक है जो C++ को अप्रचलित बनाता है। सिद्धांत रूप में, हालांकि, यह सी ++ से बेहतर नहीं है क्योंकि यह उसी बैकएंड का उपयोग करता है। यह GPU प्रोग्रामिंग के लिए CUDA और CPU के लिए LLVM का उपयोग करता है। व्यवहार में, चूंकि इसे हर नए आर्किटेक्चर के लिए समय से पहले पुनर्निर्माण की आवश्यकता नहीं होती है, Numba समाधान हर नए हार्डवेयर और इसके उपलब्ध अनुकूलन के लिए बेहतर अनुकूल होते हैं।


निश्चित रूप से, स्पाइरल की तरह स्पष्ट प्रदर्शन लाभ प्राप्त करना बेहतर होगा। लेकिन सर्पिल एक शोध परियोजना से अधिक है, यह सी ++ को मार सकता है लेकिन अंततः, और केवल अगर यह भाग्यशाली है। पायथन के साथ Numba वास्तविक समय में C ++ का गला घोंट देता है। क्योंकि यदि आप पायथन में लिख सकते हैं और सी ++ का प्रदर्शन कर सकते हैं, तो आप सी ++ में क्यों लिखना चाहेंगे?


सी ++ हत्यारा संख्या 3। फॉरवर्डकॉम

चलो एक और खेल खेलते हैं। मैं आपको कोड के तीन टुकड़े दूंगा, और आप अनुमान लगाएंगे कि उनमें से कौन सा, या शायद अधिक, असेंबली में लिखा गया है। वे यहाँ हैं:


 invoke RegisterClassEx, addr wc ; register our window class invoke CreateWindowEx,NULL, ADDR ClassName, ADDR AppName,\ WS_OVERLAPPEDWINDOW,\ CW_USEDEFAULT, CW_USEDEFAULT,\ CW_USEDEFAULT, CW_USEDEFAULT,\ NULL, NULL, hInst, NULL mov hwnd,eax invoke ShowWindow, hwnd,CmdShow ; display our window on desktop invoke UpdateWindow, hwnd ; refresh the client area .while TRUE ; Enter message loop invoke GetMessage, ADDR msg,NULL,0,0 .break .if (!eax) invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .endw


 (module (func $add (param $lhs i32) (param $rhs i32) (result i32) get_local $lhs get_local $rhs i32.add) (export "add" (func $add)))


 v0 = my_vector // we want the horizontal sum of this int64 r0 = get_len ( v0 ) int64 r0 = round_u2 ( r0 ) float v0 = set_len ( r0 , v0 ) while ( uint64 r0 > 4) { uint64 r0 >>= 1 float v1 = shift_reduce ( r0 , v0 ) float v0 = v1 + v0 }


तो कौन सा, या एक से अधिक, असेंबली में है? अगर आपको लगता है कि तीनों बधाई हो! आपका अंतर्ज्ञान पहले से बहुत बेहतर हो गया है!


पहला MASM32 में है। यह "अगर" और "जबकि" लोगों के साथ एक मैक्रोअसेंबलर है, जिसमें लोग देशी विंडोज एप्लिकेशन लिखते हैं। Microsoft उत्साह से Win32 API के साथ विंडोज़ की पिछड़ी संगतता की रक्षा करता है, इसलिए सभी MASM32 प्रोग्राम जो कभी भी लिखे गए हैं, आधुनिक पीसी पर भी अच्छी तरह से काम करते हैं।


विडंबना क्या है, पीडीपी-7 से पीडीपी-11 तक यूनिक्स अनुवाद को आसान बनाने के लिए सी का आविष्कार किया गया था। इसे 70 के दशक के हार्डवेयर आर्किटेक्चर के कैम्ब्रियन विस्फोट से बचने में सक्षम पोर्टेबल असेंबलर के रूप में डिजाइन किया गया था। लेकिन XXI सदी में, हार्डवेयर आर्किटेक्चर इतनी धीमी गति से विकसित होता है, जो प्रोग्राम मैंने 20 साल पहले MASM32 में लिखे थे, आज इकट्ठा होते हैं और पूरी तरह से चलते हैं, लेकिन मुझे इस बात का कोई भरोसा नहीं है कि C++ एप्लिकेशन जिसे मैंने पिछले साल CMake 3.21 के साथ बनाया था, आज CMake के साथ बनेगा 3.25।


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


वेब असेंबली कोड आपके हार्डवेयर आर्किटेक्चर पर बिल्कुल भी निर्भर नहीं करता है। यह जिस मशीन की सेवा करता है वह अमूर्त, आभासी, सार्वभौमिक है, इसे आप जो चाहें कह सकते हैं। यदि आप इस पाठ को पढ़ सकते हैं, तो आपको अपनी भौतिक मशीन पर पहले से ही एक मिल गया है।


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


हम जानते हैं कि सभी सबसे आम वास्तुशिल्प परिवार: x64, ARM और RISC-V के अलग-अलग निर्देश सेट हैं। लेकिन इसे इस तरह रखने का एक अच्छा कारण कोई नहीं जानता। सभी आधुनिक प्रोसेसर, शायद सबसे सरल के अलावा, उस कोड को नहीं चलाते हैं जिसके साथ आप इसे फीड करते हैं, लेकिन माइक्रोकोड वे आपके इनपुट का अनुवाद करते हैं। तो यह केवल M1 नहीं है जिसमें Intel के लिए पिछड़ी संगतता परत है, प्रत्येक प्रोसेसर में अनिवार्य रूप से अपने सभी पुराने संस्करणों के लिए पिछड़ी संगतता परत होती है।


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


आगे की अनुकूलता परत के साथ, यह कभी भी अप्रचलित नहीं होगा। यही तो बात है।


असेम्बली प्रोग्रामिंग भी एक मिथक द्वारा रोकी जाती है कि असेम्बली में लिखना कठिन है और इसलिए अव्यावहारिक है। फॉग का प्रस्ताव इस समस्या को भी संबोधित करता है। अगर लोगों को लगता है कि असेंबली में लिखना कठिन है, और सी में लिखना मुश्किल नहीं है, तो चलिए असेंबलर को सी जैसा बनाते हैं। कोई समस्या नहीं है। आधुनिक असेम्बली भाषा के लिए ठीक वैसा ही दिखने का कोई अच्छा कारण नहीं है जैसा कि उसके दादाजी 50 के दशक में दिखते थे।


आपने अभी-अभी तीन विधानसभा नमूने स्वयं देखे हैं। उनमें से कोई भी "पारंपरिक" विधानसभा की तरह नहीं दिखता है और कोई भी नहीं होना चाहिए।


तो, फॉरवर्डकॉम वह असेंबली है जिसमें आप इष्टतम कोड लिख सकते हैं जो कभी अप्रचलित नहीं होगा, और जो आपको "पारंपरिक" असेंबली सीखने नहीं देता है। सभी व्यावहारिक विचारों के लिए, यह भविष्य का सी है। सी ++ नहीं।

तो С++ आखिर कब मरेगा?

हम एक उत्तर आधुनिक दुनिया में रहते हैं। अब कुछ भी नहीं मरता लेकिन लोग। जिस तरह लैटिन वास्तव में कभी नहीं मरा, जैसे COBOL, Algol 68, और Ada, - C ++ जीवन और मृत्यु के बीच शाश्वत अर्ध-अस्तित्व के लिए अभिशप्त है। सी ++ वास्तव में कभी नहीं मरेगा, इसे केवल नई और अधिक शक्तिशाली प्रौद्योगिकियों द्वारा मुख्यधारा से बाहर कर दिया जाएगा।


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


यदि मैं C++ का व्यापार “नहीं C++” के लिए करता हूं, तो मेरा 80% काम बिल्कुल वैसा ही रहेगा। सी ++ मेरे द्वारा किए जाने वाले अधिकांश कार्यों के लिए बस अप्रासंगिक है। क्या इसका मतलब यह हो सकता है कि मेरे लिए सी ++ पहले ही 80% मर चुका है?



स्थिर प्रसार द्वारा विकसित लीड छवि।