Uploaded avatar of iHiD

यह है निबली नवंबर

@iHiD
लगभग 3 साल पहले
वीडियो

परिचय

नमस्ते सबको। नवंबर में आपका स्वागत है। उम्मीद है आप अच्छे होंगे।

हमारा अक्टूबर बहुत ही व्यस्त रहा। हमने अभी-अभी कम्युनिटी सॉल्यूशन में एक बड़ा सुधार लॉन्च किया है। अब हम इनमें डुप्लीकेट हटा देते हैं, इसलिए मिलते-जुलते सॉल्यूशन सिर्फ एक बार दिखते हैं। हमने क्रम तय करने के नए विकल्प जोड़े हैं और कोड से खोजने की सुविधा भी। और अगर आप C# देखें, तो पाएँगे कि हमने अलग-अलग प्रोग्रामिंग कॉन्सेप्ट के हिसाब से फिल्टर करने की सुविधा भी जोड़ी है। तो अब आप ऐसे सॉल्यूशन ढूँढ सकते हैं जिनमें बिट शिफ्टिंग, रिकर्शन या आपकी पसंद की कोई भी चीज़ इस्तेमाल हुई हो। कम्युनिटी वीक में हम इसे दूसरे ट्रैकों पर भी लागू करेंगे।

लेकिन अभी के लिए, चलिए #12in23 पर ध्यान दें। अक्टूबर एक दिलचस्प महीना था, जिसमें हमने ऑब्जेक्ट-ओरिएंटेड भाषाएँ खँगालीं, लेकिन इस महीने हम एकदम कठिन हिस्से की ओर बढ़ रहे हैं। हमारा ध्यान असेंबली भाषाओं पर है, और खास तौर पर MIPS असेंबली, x86-64 असेंबली और WebAssembly पर। हमेशा की तरह, Erik हमें बताएँगे कि इन भाषाओं को दिलचस्प और अनोखा क्या बनाता है।

बैज

हमेशा की तरह, इन भाषाओं में कोई भी 5 अभ्यास पूरे करके आप Nibbly November बैज कमा सकते हैं। हमारे पास साल भर का बैज भी है, और मुझे पता है कि आपमें से कई लोग उसकी ओर बढ़ रहे हैं। उसके लिए हमारे पास 5 चुनिंदा अभ्यास हैं जिन्हें आप पूरा कर सकते हैं। वे ये हैं:

  • Pop Count: किसी संख्या में 1 बिट गिनिए
  • Grains: दोगुनी होती खानों वाले शतरंज के बोर्ड पर दानों की संख्या निकालिए
  • Resistor Color: रेसिस्टर बैंड के रंग को उसके संख्यात्मक रूप में बदलिए
  • Rotational Cipher: रोटेशनल साइफर लागू कीजिए (यानी सीज़र साइफर)
  • Nucleotide Count: निकालिए कि DNA स्ट्रिंग में हर न्यूक्लियोटाइड कितनी बार आता है

पृष्ठभूमि

इसका नाम Nibble November क्यों?

तो, जैसा कि आप शायद जानते हैं, एक बाइट में 8 बिट होते हैं। और एक निबल में 4 बिट। नाम की बात तब समझ आने लगती है जब आप byte के y को i से बदल दें, तो bite बनता है। और nibble यानी एक छोटा सा bite।

असेंबली भाषा क्या है?

तो, चलिए कुछ बुनियादी बातों से शुरू करते हैं। एक CPU इंस्ट्रक्शन चलाता है, जैसे "दो संख्याएँ जोड़ना" या "बिट्स को बाईं ओर शिफ्ट करना", वगैरह। इन इंस्ट्रक्शन को मशीन कोड इंस्ट्रक्शन कहते हैं, और ये बस बिट्स के कुछ खास क्रम से ज़्यादा कुछ नहीं होते। किसी प्रोग्राम को चलाना "बस" (उद्धरण चिह्नों में) CPU का इन बिट क्रमों को संसाधित करना और चलाना है।

चूँकि इंस्ट्रक्शन को सीधे बिट्स के क्रम के रूप में लिखना कठिन और गलतियों की संभावना से भरा होता है, इसलिए Kathleen और Andrew Donald Booth ने 1947 में ही मशीन कोड इंस्ट्रक्शन को दर्शाने के लिए एक ऐसी भाषा बनाई जो इंसानों के लिए ज़्यादा आसान थी। मशीन कोड इंस्ट्रक्शन को दर्शाने वाली ऐसी भाषा को असेंबली भाषा कहते हैं। फिर इस असेंबली भाषा को एक "असेंबलर" की मदद से मशीन कोड इंस्ट्रक्शन में बदला जाता है।

असेंबली भाषाओं की एक दिलचस्प बात यह है कि वे सीधे CPU आर्किटेक्चर से जुड़ी होती हैं, हालाँकि आम तौर पर ये ऑपरेटिंग सिस्टम से स्वतंत्र होती हैं।

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

असेंबली भाषा उन भाषाओं से अलग कैसे है जिनमें हम अब प्रोग्राम करते हैं?

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

मज़ेदार बात: RollerCoaster Tycoon का 99% सोर्स कोड हाथ से लिखा असेंबली कोड था! यह एक हैरान करने वाली उपलब्धि है, और जब आप खुद थोड़ी असेंबली कर लेंगे, तो इसकी कद्र और भी ज़्यादा करने लगेंगे।

क्या लोग अब भी असेंबली कोड लिखते हैं?

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

अवलोकन

MIPS

  • MIPS (Microprocessor without Interlocked Pipelined Stages) रिड्यूस्ड इंस्ट्रक्शन सेट कंप्यूटर (RISC) इंस्ट्रक्शन सेट आर्किटेक्चर का एक परिवार है
  • इसे MIPS Computer Systems ने बनाया और पहली बार 1985 में जारी किया गया
  • कई वर्शन: MIPS I, II, III, IV, V और MIPS32/64. पहले दो वर्शन सिर्फ 32-बिट थे, लेकिन MIPS III ने 64-बिट का सपोर्ट जोड़ा।
  • कई वैकल्पिक एक्सटेंशन, जैसे SIMD इंस्ट्रक्शन और कम्प्रेशन
  • बाद के RISC आर्किटेक्चरों पर इसका बहुत गहरा असर पड़ा
  • MIPS ने 2021 में घोषणा की कि MIPS आर्किटेक्चर पर अब काम नहीं किया जा रहा है और वे RISC-V पर चले गए (जो एक ओपन-सोर्स, रॉयल्टी-फ्री आर्किटेक्चर है)
  • ज़्यादातर एम्बेडेड सिस्टम (जैसे राउटर) और सर्वर में इस्तेमाल होता है (Silicon Graphics के कंप्यूटर इसे इस्तेमाल करते थे, जो फिल्मों में SFX के लिए मशहूर थे), NEC Cenju-4 सुपरकंप्यूटर में, Tesla की Model S कार में, NASA के New Horizons अंतरिक्ष यान में, लेकिन साथ ही विश्वविद्यालयों में असेंबली पढ़ाने के लिए और कई गेमिंग कंसोल में (जैसे मूल PlayStation, Playstation Portable और Nintendo 64)

x86-64 असेंबली

  • इसे AMD ने बनाया और 1999 में AMD64 आर्किटेक्चर के रूप में जारी किया
  • यह x86 इंस्ट्रक्शन सेट का 64-बिट वर्शन है, जिसकी शुरुआत 1978 में हुई जब Intel ने अपना 8086 माइक्रोप्रोसेसर लॉन्च किया। वह 16-बिट प्रोसेसर था, लेकिन बाद में 80386 ने 32-बिट इंस्ट्रक्शन जोड़े, और वही इंस्ट्रक्शन सेट x86 का पर्याय बन गया।
  • 64-बिट से जो मुख्य चीज़ संभव हुई वह थी ज़्यादा मेमोरी को एड्रेस करना (32-बिट एड्रेसिंग 4GB तक सीमित है), जो अब तक एक अड़चन बन गई थी। 64-बिट सिद्धांत रूप में 16 एक्ज़ाबाइट तक एड्रेस कर सकता है, लेकिन फिलहाल सिर्फ 48 बिट इस्तेमाल होते हैं, जिससे 256 TB तक एड्रेस किया जा सकता है (ज़रूरत पड़ने पर बाद में बढ़ाया जा सकता है)
  • AMD64, x86 इंस्ट्रक्शन सेट को आगे बढ़ाता है और इसे एक कंपैटिबिलिटी मोड के ज़रिए मौजूदा 16- और 32-बिट ऐप्लिकेशनों के साथ पूरी तरह संगत बनाया गया था
    • Intel ने IA-64 को AMD की भागीदारी के बिना बनाया था। यह एक नया, बहुत अलग और पीछे की ओर असंगत 64-बिट इंस्ट्रक्शन सेट था। अंत में AMD64 जीत गया और Intel ने इसका अपना वर्शन लागू किया (सिर्फ मामूली सेमांटिक अंतरों के साथ)
  • हर जगह इस्तेमाल होता है। वर्कस्टेशन से लेकर सर्वर तक (सुपरकंप्यूटर समेत), एम्बेडेड सिस्टम से लेकर गेमिंग कंसोल तक (जैसे PS5 और Xbox Series X)।

WebAssembly

  • इसे W3C ने बनाया, जो वेब टेक्नोलॉजीज़ के लिए मानक तय करने वाली संस्था है
  • डिज़ाइन के उद्देश्य हैं:
    • तेज़, सुरक्षित और पोर्टेबल
    • कुशल और पोर्टेबल रूप
  • पहले के दिनों में, वेब पर तेज़ निष्पादन आम तौर पर खास ब्राउज़र प्लगइन के ज़रिए होता था, जैसे Flash और Silverlight, क्योंकि JavaScript खुद हाई-परफॉर्मेंस कंप्यूटिंग के लिए बहुत उपयुक्त नहीं है। इन प्लगइन की सबसे बड़ी कमियाँ यह थीं कि इनमें अक्सर बहुत सारी सुरक्षा समस्याएँ होती थीं और ये मानकीकृत नहीं थे।
    • Mozilla ने asm.js बनाया, जो JavaScript का एक उपसमुच्चय था जिसका उद्देश्य ब्राउज़र में बहुत अच्छे प्रदर्शन के साथ कोड चलाने की सुविधा देना था। यह उसने टाइप की एकरूपता (टाइप का गतिशील रूप से बदलना नहीं) और गार्बेज कलेक्शन के बिना हासिल किया। भाषाएँ फिर asm.js में कंपाइल कर सकती थीं और वेब पर चलने पर अच्छा प्रदर्शन पा सकती थीं। फिर भी यह JS ही था, इसलिए संभावनाएँ सीमित थीं। इसलिए एक नई भाषा का प्रस्ताव आया: WASM।
  • यह असेंबली जैसी भाषा है, इस अर्थ में कि यह चलाने के लिए इंस्ट्रक्शन का एक समूह देती है। सबसे अहम बात, यह किसी खास CPU से बँधी नहीं है, इसलिए यह प्लेटफॉर्म-स्वतंत्र है और हर प्लेटफॉर्म के लिए एक इम्प्लीमेंटेशन (वर्चुअल मशीन) चाहती है। इसका मतलब है कि WebAssembly असल में बाइटकोड है, मशीन कोड नहीं
  • स्टैटिकली टाइप्ड (JS से एक बड़ा अंतर)
  • आम तौर पर अहेड-ऑफ-टाइम या जस्ट-इन-टाइम कंपाइलेशन इस्तेमाल करती है (लेकिन इंटरप्रेट भी की जा सकती है)
  • ओपन स्टैंडर्ड है और दो चीज़ें परिभाषित करती है:
    • एक बाइनरी फॉर्मेट
    • एक टेक्स्ट फॉर्मेट (जिसे बाइनरी फॉर्मेट में कंपाइल किया जाता है)
  • सभी प्रमुख ब्राउज़रों में इसके इम्प्लीमेंटेशन मौजूद हैं
  • कई ऐसे वेब पेजों में इस्तेमाल होती है जिन्हें उच्च प्रदर्शन चाहिए, जैसे Google Earth, Figma, Unity और Autocad। यह सर्वर-साइड पर भी लोकप्रियता बढ़ा रही है, जैसे माइक्रोसर्विस चलाने के लिए, SaaS प्लेटफॉर्म पर (जैसे CloudFlare workers) या Docker में चलाने के लिए

और प्रोग्रामिंग के नज़रिए से, ये एक-दूसरे से कैसे अलग हैं?

MIPS

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

x86-64 असेंबली

  • रजिस्टर-मेमोरी आर्किटेक्चर इस्तेमाल करता है, जिसमें काम रजिस्टरों के साथ ही मेमोरी पर (या मेमोरी से) भी किया जा सकता है

WebAssembly

  • स्टैक-आधारित प्रोग्रामिंग इस्तेमाल करती है (कोई रजिस्टर नहीं), साथ ही मेमोरी से और मेमोरी में डेटा पढ़ने का विकल्प देती है

इन भाषाओं को बेहतरीन बनाने वाली बातें क्या हैं?

MIPS

  • छोटा। MIPS इंस्ट्रक्शन सेट के सारे इंस्ट्रक्शन एक ही पेज पर आ जाते हैं
  • स्थापित कॉलिंग कन्वेंशन यह समझने में मदद करते हैं कि उपलब्ध रजिस्टरों का इस्तेमाल कैसे करना है, जैसे आर्गुमेंट पास करने के लिए कौन-से और नतीजे लौटाने के लिए कौन-से रजिस्टर इस्तेमाल करने हैं।
  • स्थिर। आखिरी वर्शन 2014 में जारी हुआ था
  • इस पर बहुत ज़्यादा दस्तावेज़ मौजूद हैं, खास तौर पर अकादमिक किताबों में
  • वास्तविक दुनिया में बहुत इस्तेमाल। अरबों डिवाइस

x86-64 असेंबली

  • यह x64 का एक एक्सटेंशन होते हुए भी, इसमें बहुत सारे नए फीचर जोड़े गए, जिनमें शामिल हैं:
    • 64-बिट पूर्णांक का सपोर्ट
    • अतिरिक्त रजिस्टर
    • SSE इंस्ट्रक्शन (वेक्टर इंस्ट्रक्शन)
    • रिलेटिव डेटा एक्सेस (शेयर्ड लाइब्रेरी इस्तेमाल करते समय ज़्यादा कुशल)
    • No-Execute Bit (सुरक्षा फीचर, जो मेमोरी के कुछ खास पेजों में कोड चलने से रोकता है)
  • परिचित। चूँकि यह x86 इंस्ट्रक्शन सेट को आगे बढ़ाता है, जो लोग x86 इंस्ट्रक्शन सेट से परिचित हैं उनके लिए सीखना अपेक्षाकृत आसान होगा बहुत विस्तृत और बारीक दस्तावेज़ीकरण
  • स्थिर। हालाँकि नए वर्शन नियमित रूप से जुड़ते रहते हैं, मूल हिस्सा बेहद स्थिर और पीछे की ओर संगत बना रहता है

WebAssembly

  • स्टैक-आधारित WebAssembly वर्चुअल मशीन असली प्रोसेसरों (RISC समेत) की असेंबली भाषाओं के मुकाबले हल्की और सरल है। इस वजह से इसके लिए कंपाइल करना अपेक्षाकृत आसान है।
  • WebAssembly टेक्स्ट फॉर्मेट परिचित इम्पेरेटिव शैली पाने के लिए S-Expression "शुगर" इस्तेमाल करता है, जिसे फिर स्टैक-आधारित कोड में बदल दिया जाता है। S-Expression वाले रूप को "शुगर्ड फॉर्म" कहते हैं, और यह दूसरे रूप में "डीशुगर" हो जाता है, जो बाइनरी में मौजूद कोड के बराबर होता है। S-expression उन सभी के लिए परिचित होंगे जिन्होंने कभी LISP के साथ काम किया है
  • JavaScript के साथ मज़बूत इंटरऑप। JavaScript से और JavaScript में डेटा पास करना आसान है। एक ज़रूरी चेतावनी: WASM (अभी तक) DOM के साथ इंटरैक्ट करने की सुविधा नहीं देता
  • इसमें लगातार सुधार हो रहा है। सिर्फ WASM वर्चुअल मशीनों में ही सुधार नहीं हो रहा, बल्कि मानक खुद भी सक्रिय रूप से विकसित किया जा रहा है। ढेरों नए फीचर बनाए और उन पर काम किए जा रहे हैं, जैसे SIMD से जुड़े इंस्ट्रक्शन, गार्बेज कलेक्शन, थ्रेड, टेल-कॉल ऑप्टिमाइज़ेशन और बहुत कुछ
  • सुरक्षित। कोड को सत्यापित किया जाता है और सैंडबॉक्स वाले वातावरण में चलाया जाता है, जो JavaScript या नेटिव असेंबली भाषाओं के मुकाबले ज़्यादा स्टैटिक वैलिडेशन देता है। इसके सेमांटिक्स सुपरिभाषित हैं, जिससे इन्हें जाँचना और समझना आसान होता है

सबसे खास विशेषताएँ

MIPS

  • कार्यक्षमता। MIPS प्रोसेसर बहुत कुशल हैं, जिससे ये एम्बेडेड सिस्टम के लिए बढ़िया हैं।
  • प्रदर्शन। शानदार प्रदर्शन, इसीलिए MIPS सुपरकंप्यूटरों में इस्तेमाल हुआ
  • सीखना आसान। इंस्ट्रक्शन कम हैं और हर इंस्ट्रक्शन बस एक सरल काम करता है, जिससे इसे सीखना आसान हो जाता है। पढ़ाने के लिए बढ़िया।

x86-64 असेंबली

  • शक्तिशाली। x86-64 को दशकों में तराशा गया है, और इसमें ढेरों इंस्ट्रक्शन हैं जो प्रदर्शन में मदद करते हैं। इसका एक उदाहरण SIMD (Single Instruction, Multiple Data) है, यानी ऐसे इंस्ट्रक्शन जो, खैर, एक ही इंस्ट्रक्शन को कई डेटा पर एक साथ चला सकते हैं।
  • हर जगह मौजूद। जो डिवाइस x86-64 चलाते हैं वे हर जगह हैं। Intel और AMD के CPU इसे लागू करते हैं। यह काफी समय से डी-फैक्टो मानक रहा है
  • नियमित रूप से अपडेट होता है। जैसे नए वेक्टर इंस्ट्रक्शन, SSE3-5, AVX, AVX-512 और बहुत कुछ के साथ

WebAssembly

  • कुशल। बाइनरी फॉर्मेट छोटा है और इसे एक ही तेज़ पास में डिकोड, वैलिडेट और कंपाइल किया जा सकता है। यह स्ट्रीम करने लायक भी है, जिससे सारा डेटा देखे जाने से पहले ही डिकोडिंग, वैलिडेशन और कंपाइलेशन जल्द से जल्द शुरू किया जा सकता है। और यह समानांतर भी है। इससे यह हाई-परफॉर्मेंस वेब ऐप्लिकेशनों के लिए एकदम सही बनती है।
  • कंपाइलेशन के लिए बढ़िया लक्ष्य। यह कई भाषाओं के कोड को वेब पर चलाने देती है। ज़्यादातर प्रमुख भाषाएँ WebAssembly बाइनरी में कंपाइल करने का सपोर्ट करती हैं, जिसका मतलब है कि आपका कोड JavaScript लिखे बिना वेब पर चल सकता है। कुछ भाषाएँ आपके कोड को WebAssembly में कंपाइल नहीं करतीं, बल्कि रनटाइम को WebAssembly में कंपाइल करती हैं, जो फिर बिना बदले बाइटकोड चला सकता है।
  • डिप्लॉय करना और चलाना आसान। आपको बस एक वर्चुअल मशीन चाहिए जो बाइटकोड को इंटरप्रेट कर सके, और सभी प्रमुख ब्राउज़रों में एक मौजूद है।
  • यह वेब से बँधी नहीं है, बल्कि सर्वर-साइड पर भी चल सकती है। WebAssembly System Interface (WASI) एक इंटरफेस (ABI और API) है जिसे किसी भी प्लेटफॉर्म पर पोर्टेबल रहने के लिए बनाया गया है। यह POSIX (Unix सिस्टमों के लिए मानक इंटरफेस) जैसा है और I/O जैसी चीज़ें देता है। इसकी डिज़ाइन में सुरक्षा एक अहम हिस्सा है, जिसमें सैंडबॉक्सिंग और कैपेबिलिटी-ओरिएंटेड होना शामिल है (फाइलों या सॉकेट जैसी चीज़ों के लिए आपको साफ़ तौर पर अनुमति माँगनी पड़ती है)। WASI में भाषाओं के बीच आसान इंटरफेसिंग की संभावना भी है। Docker के सह-संस्थापक Solomon Hykes ने 2019 में लिखा था, "अगर 2008 में WASM+WASI मौजूद होता, तो हमें Docker बनाने की ज़रूरत नहीं पड़ती"

किसे चुनें

  • अगर आपने कभी असेंबली भाषा के साथ काम नहीं किया है, तो WebAssembly शायद शुरुआत करने के लिए सबसे आसान भाषा है। फिर भी, अगर आप ऐसी असेंबली भाषा सीखना चाहते हैं जो मशीन कोड में कंपाइल होती है, तो MIPS असेंबली आज़माइए
  • अगर आप x86-64 मशीन पर काम कर रहे हैं (बहुत संभव है), तो x86-64 असेंबली आज़माइए
  • अगर आप LISP से परिचित हैं, तो आपको यह अच्छा लगेगा कि WebAssembly S-expression इस्तेमाल करती है
  • अगर आप वेब ऐप्स के साथ काम कर रहे हैं, तो WebAssembly सबसे तार्किक विकल्प है
  • अगर आपको प्रदर्शन की परवाह है, तो x86-64 और MIPS बढ़िया विकल्प हैं। या अगर आपको वेब प्रदर्शन की परवाह है, तो WebAssembly आज़माइए
01 नवंबर 2023 · क्या यह काम की लगी?