2 पॉइंट द्वारा GN⁺ 2024-04-27 | 1 टिप्पणियां | WhatsApp पर शेयर करें

NAND: वेब में इम्प्लीमेंट किया गया पूर्ण Turing-equivalent 16-bit computer

  • NAND, NAND gates और clock की मदद से वेब में emulated एक Turing-equivalent 16-bit computer है
  • NAND का अपना CPU, machine code, assembly language, assembler, VM language, VM translator, programming language, compiler, IDE, UI है
  • NAND, Nand to Tetris course और उससे संबंधित किताब में निर्दिष्ट Jack-VM-Hack platform पर आधारित है

प्रोग्राम उदाहरण

Average

  • संख्याएँ इनपुट लेकर औसत निकालने वाला एक सरल प्रोग्राम
  • control flow, arithmetic operations, I/O, dynamic memory allocation को दिखाता है

Pong

  • Pong गेम के जरिए भाषा के object-oriented model को दिखाता है
  • arrow keys से paddle को बाएँ-दाएँ चलाकर गेंद को उछालें
  • हर बार उछलने पर paddle छोटा होता जाता है, और गेंद स्क्रीन के नीचे गिरते ही गेम खत्म

2048

  • 2048 गेम के जरिए recursion और complex application logic को दिखाता है
  • arrow keys से 4x4 grid में संख्याओं को चलाएँ
  • एक जैसी संख्याएँ टकराने पर आपस में मिल जाती हैं
  • 2048 tile तक पहुँचना जीत है, लेकिन उसके बाद भी आगे जोड़ते रह सकते हैं
  • board भर जाए और कोई move न बचे तो गेम खत्म

Overflow

  • infinite recursion से जानबूझकर stack overflow पैदा कर virtual machine से बाहर निकलने वाला प्रोग्राम
  • इस बात का फायदा उठाता है कि stack overflow रोकने के लिए कोई runtime check नहीं है
  • चलाने पर stack pointer की value लगातार प्रिंट करता है
  • जब stack तय memory space के अंत तक पहुँचकर heap memory में घुस जाता है, तो print statements विस्फोटक तरीके से गलत काम करने लगते हैं

SecretPassword

  • इस बात का फायदा उठाने वाला प्रोग्राम कि runtime stack smashing को नहीं रोकता, और इस तरह ऐसी function को call करता है जिसे सामान्य रूप से access नहीं किया जा सकता
  • इसके लिए NAND के stack frame layout की समझ जरूरी है
  • यह user को किसी भी memory address पर किसी भी value से overwrite करने देता है
  • अगर किसी function के return address को दूसरी function के address से overwrite कर दें, तो arbitrary code execute किया जा सकता है
  • stack addresses और assembler को manually inspect करके मिले किसी खास memory location और overwrite value को इनपुट करें, तो इस आइडिया को काम करते देख सकते हैं

GeneticAlgorithm

  • NAND के कई components में से development में सबसे ज्यादा समय लेने वाला हिस्सा
  • simple machine learning का उपयोग करने वाला biological simulation
  • हर dot का "brain" acceleration vectors से बना है, जो लक्ष्य तक natural selection के जरिए evolve होता है
  • हर generation में, लक्ष्य के ज्यादा करीब "मरने" वाले dots के अगले generation के parent चुने जाने की संभावना अधिक होती है
  • reproduction brain में mutation लाता है, और natural evolution को प्रभावी ढंग से simulate करता है
  • performance limits के कारण, कई optimization techniques का उपयोग करके hardware limitations को bypass किया गया है और इसे संभव बनाया गया है

Jack में programming करना

  • Jack में programming करते समय सबसे महत्वपूर्ण बात यह है कि operator precedence नहीं है। यही वजह हो सकती है कि आपका प्रोग्राम सही काम न करे।
  • 4 * 2 + 3(4 * 2) + 3, if (~x & y)if ((~x) & y) की तरह parentheses से precedence को स्पष्ट करना चाहिए

Jack का परिचय

  • NAND अपना पूरा technology stack खुद रखता है
  • Jack एक weakly typed object-oriented language है। सरल शब्दों में, Java syntax वाली C language
  • आइए एक उदाहरण से सीखें

Custom data types

  • Jack तीन basic types int, char, boolean को support करता है
  • जरूरत के अनुसार इन्हें abstract data types से बढ़ाया जा सकता है
  • object-oriented programming का ज्ञान सीधे लागू किया जा सकता है
  • उदाहरण में Point class के जरिए abstract space में एक point को define किया गया है
  • field variables से data type की instance-specific properties declare की जाती हैं
  • point को manipulate करने के लिए public method functions दिए जाते हैं, ताकि caller point जोड़ सके या दो points के बीच की दूरी निकाल सके
  • सभी field variables private scope में होते हैं। इन्हें access करने के लिए method functions के जरिए उपलब्ध कराना पड़ता है
  • data classes में dispose method define करना एक convention है
  • function, method call syntax देखें

Weak type conversion

  • कहा गया है कि Jack पर Java का बड़ा प्रभाव है, लेकिन यह सिर्फ एक simple facade है
  • Java एक strongly typed language है और downcasting, polymorphism, inheritance जैसी complex type features को support करती है
  • दूसरी ओर Jack वास्तव में सिर्फ एक signed 16-bit integer को support करता है
  • यही कारण है कि Jack weakly typed है
  • इसलिए Jack compiler assignment और operations में अलग-अलग types मिलाने पर ज्यादा ध्यान नहीं देता
  • Jack फिर भी एक मजबूत और functional object-oriented model देता है
  • इससे यह समझने में मदद मिलेगी कि type conversion कब और कैसे करना चाहिए

Manual memory management

  • Jack एक ऐसी language है जिसमें memory को manually manage करना पड़ता है
  • जो memory अब जरूरी न हो, उसे सही समय पर free करने का ध्यान रखना चाहिए
  • नहीं तो Jack OS मानेगा कि memory leak हो रहा है
  • best practice यह है कि हर class के लिए allocation cleanup को ठीक से encapsulate करने वाला dispose method लिखा जाए
  • जब object की जरूरत न रहे, तब इस method को call करने से heap memory खत्म होने से बचा जा सकता है
  • अगर आपने C जैसी दूसरी manual memory management languages इस्तेमाल की हैं, तो यह परिचित लगेगा
  • फर्क यह है कि Jack OS arrays और strings को stack की बजाय heap में रखता है
  • String.dispose देखें, इससे समझ आएगा कि dispose method कैसे लिखना है

Undefined behavior

Operator precedence

  • यह इतना महत्वपूर्ण है कि इसे आगे खिसका दिया गया

Less-than और greater-than operators

  • Jack की comparison expressions a > b, a < b सरल दिखती हैं, लेकिन गणितीय रूप से हमेशा सही नहीं होतीं
  • virtual machine इन्हें a - b > 0 में बदल देती है। लेकिन a - b overflow हो सकता है
  • 20000 > -20000 का मूल्यांकन कैसे होगा? 20000 - (-20000) > 0, यानी -25336 > 0, इसलिए false
  • लेकिन 20000 > -10000 का परिणाम 30000 > 0, यानी true होता है
  • अगर a और b के absolute values का अंतर 32767 से बड़ा हो, तो a > b और a < b गलत हो जाते हैं। नहीं तो ठीक है
  • यह bug नहीं, बल्कि Nand to Tetris के साथ incompatibility है। compatibility बनाए रखने के लिए इस behavior को ठीक नहीं किया जाएगा

-32768

  • -32768 एकमात्र संख्या है जिसमें यह अनोखी property है कि -(-32768) = -32768। यानी इसका कोई positive जोड़ा नहीं है
  • इसके कारण seemingly valid logic errors पैदा हो सकते हैं
  • क्योंकि -x को अंदरूनी रूप से ~(x-1) की तरह handle किया जाता है
  • अगर x में -32768 रखा जाए, तो x-1 = ~x संतुष्ट होता है। ~(~x) फिर x के बराबर हो जाता है
  • यहाँ क्या हुआ? NAND एक 16-bit machine है, इसलिए -32768 में से 1 घटाने पर परिणाम bits को flip करने जैसा हो जाता है
  • महत्वपूर्ण बात यह है कि unary minus को handle करते समय logic errors को ध्यान में रखा जाए
  • -32768 case को check करके सही तरह handle करना programmer की जिम्मेदारी है

कम arguments के साथ function call

  • यह एक स्पष्ट undefined behavior है, जिसे अलग से समझाने की जरूरत नहीं

Improper type casting

  • Array के रूप में किसी variable को किसी भी type में cast किया जा सकता है
  • मौजूद न होने वाली instance method को call करने पर undefined behavior होता है
  • compiler इतना smart नहीं है कि इसे detect कर सके

Stack overflow

  • Overflow प्रोग्राम देखें

Stack frame या internal registers को modify करना

  • stack frame या 256~2047, 1~15 address range के internal registers को modify करने पर undefined behavior हो सकता है
  • आमतौर पर यह तब तक संभव नहीं, जब तक Memory.poke या negative array indices का गलत उपयोग न किया जाए
  • SecretPassword प्रोग्राम देखें

Hardware specs

  • 1970 के दशक के बाद 16-bit computing के अप्रचलित होने की वजह है

  • 32-bit या 64-bit की तुलना में इसकी processing power और memory capacity सीमित है, इसलिए यह modern software की जरूरतों को पूरा नहीं कर पाती

  • NAND भी इसका अपवाद नहीं है

  • 16GiB MacBook की तुलना में NAND के पास सिर्फ 4KiB RAM है। यह मात्र 0.00002% है

  • फिर भी, यह हमें चाँद तक ले जाने जितना तो कर ही सकता है

  • Jack OS, 4KiB में से 14,336 memory addresses heap के लिए reserve करता है। यह असामान्य रूप से कम संख्या है

  • इसलिए यह बेहद जरूरी है कि Jack applications memory को कुशलता से allocate और free करें

  • अगर आपकी योजना बहुत महत्वाकांक्षी है, तो heap memory खत्म हो सकती है और आपको data types और logic को पूरी तरह फिर से लिखना पड़ सकता है

  • 4KiB में से 8,192 memory addresses screen के लिए reserve हैं

  • हर address का हर bit, 512x256 screen के pixels से linear mapping में जुड़ा है। LSb 0 bit numbering उपयोग होती है

  • memory address 24,576 keyboard के लिए reserve है

  • दबाई गई key का ASCII code value वहाँ दिखाई देता है

  • लेकिन user input handle करने के लिए इसे सीधे access नहीं करना चाहिए। Jack OS की Keyboard class और संबंधित functions का उपयोग करना चाहिए

  • NAND keyboard ASCII और special keys को पहचानता है

  • static class variables के लिए 240 और global stack के लिए 1,792 memory addresses reserve हैं

  • जब तक बहुत deep recursion न करें, यह सीमा शायद समस्या नहीं बनेगी

1 टिप्पणियां

 
GN⁺ 2024-04-27
Hacker News राय
  • Nand to Tetris प्रोजेक्ट के ज़रिए कंप्यूटर के abstraction levels को गहराई से समझा जा सकता है
  • Ben Eater का 6502 कंप्यूटर किट भी इसी तरह का शैक्षिक महत्व रखता है
  • यह प्रोजेक्ट इतनी अच्छी तरह व्यवस्थित सामग्री के साथ है कि इसे कई विश्वविद्यालयी कक्षाओं के रूप में चलाया जा सकता है
  • 1990 के दशक की शुरुआत में UC Berkeley की कंप्यूटर हार्डवेयर qualification exam में भी इसी तरह केवल NAND gates से microcoded और pipelined RISC processor डिज़ाइन करने का प्रश्न पूछा गया था
    • उस समय वास्तविक निर्माण की आवश्यकता नहीं थी, केवल कागज़ पर विस्तृत डिज़ाइन लिखना होता था
  • यह प्रोजेक्ट MarquisdeGeek/gates जैसा लगता है
  • Nand2Tetris कोर्स करते समय मैं वर्चुअली ऐसा कुछ बनाना चाहता था, इसलिए इसका वास्तविक implementation प्रभावशाली है
    • इससे कंप्यूटर कैसे काम करता है, इसकी समझ काफ़ी बेहतर हुई होगी
  • यह भी इंगित किया गया कि NAND gates के अलावा clock का भी उपयोग किया गया था
  • मैंने Nand2Tetris पूरा नहीं किया, लेकिन एक प्रशंसक के रूप में इस प्रोजेक्ट को गहराई से देखना चाहूँगा
  • यह जानने की जिज्ञासा है कि कुल कितने NAND gates इस्तेमाल हुए
  • मूल सिद्धांतों के प्रति निष्ठावान इस दृष्टिकोण के लिए आभार