एक स्टैक का उद्देश्य क्या है? हमें इसकी जरूरत क्यों है?


320

इसलिए मैं अपने C # .NET एप्लिकेशन को डीबग करना सीखना अभी MSIL सीख रहा हूं।

मैंने हमेशा सोचा है: स्टैक का उद्देश्य क्या है?

मेरे प्रश्न को संदर्भ में रखने के लिए:
मेमोरी से स्टैक या "लोडिंग" में स्थानांतरण क्यों है? दूसरी ओर, स्टैक से मेमोरी या "स्टोरिंग" में स्थानांतरण क्यों है? सिर्फ उन सभी को स्मृति में क्यों नहीं रखा गया है?

  • क्या इसलिए कि यह तेज है?
  • क्या यह राम आधारित है?
  • दक्षता के लिए?

मैं इसे समझने की कोशिश कर रहा हूं ताकि CIL कोड को और अधिक गहराई से समझने में मदद मिले ।


28
स्टैक मेमोरी का एक हिस्सा है, जैसे हीप मेमोरी का दूसरा हिस्सा है।
कोडइन्चोस

@CodeInChaos आप मान प्रकार बनाम संदर्भ प्रकारों के बारे में बात कर रहे हैं? या कि IL संहिताओं के संदर्भ में समान है? ... मुझे पता है कि ढेर ढेर से ज्यादा तेज और अधिक कुशल है (लेकिन यह मूल्य / रेफ प्रकार की दुनिया में है .. जो मुझे नहीं पता कि क्या यहां भी ऐसा ही है?)
जन कार्लो विरय

15
@CodeInChaos - मुझे लगता है कि जनवरी के संदर्भ में स्टैक मशीन है जो IL के खिलाफ लिखी गई स्टैक मशीन है, जो मेमोरी के क्षेत्र के विपरीत है जो फ़ंक्शन कॉल के दौरान स्टैक फ़्रेम को स्वीकार करती है। वे दो अलग-अलग ढेर हैं, और JIT के बाद, IL स्टैक मौजूद नहीं है (x86 पर, वैसे भी)
Damien_The_Unbeliever

4
MSIL ज्ञान आपको .NET अनुप्रयोगों को डिबग करने में कैसे मदद करेगा?
पियोट्र पर्क

1
आधुनिक मशीनों पर, कोड का व्यवहार कैशिंग व्यवहार निर्माता और ब्रेकर है। स्मृति तो हर जगह है। ढेर, आमतौर पर, बस यहाँ है। यह मानते हुए कि स्टैक एक वास्तविक चीज है, न कि केवल कुछ कोड के संचालन को व्यक्त करने में उपयोग की जाने वाली अवधारणा। MSIL- रनिंग प्लेटफ़ॉर्म को कार्यान्वित करने में, कोई आवश्यकता नहीं है कि स्टैक कांसेप्ट हार्डवेयर को वास्तव में बिट्स को चारों ओर धकेलता है।
मोनिका

जवाबों:


441

अद्यतन: मुझे यह प्रश्न इतना पसंद आया कि मैंने इसे 18 नवंबर 2011 को अपने ब्लॉग का विषय बनाया । महान प्रश्न के लिए धन्यवाद!

मैंने हमेशा सोचा है: स्टैक का उद्देश्य क्या है?

मेरा मानना है कि एमएसआईएल भाषा के मूल्यांकन स्टैक का मतलब है , न कि रनटाइम पर वास्तविक प्रति-थ्रेड स्टैक।

मेमोरी से स्टैक या "लोडिंग" में स्थानांतरण क्यों है? दूसरी ओर, स्टैक से मेमोरी या "स्टोरिंग" में स्थानांतरण क्यों है? सिर्फ उन सभी को स्मृति में क्यों नहीं रखा गया है?

MSIL एक "वर्चुअल मशीन" भाषा है। C # कंपाइलर जैसे कंपाइलर CIL जनरेट करते हैं , और फिर रनटाइम के दौरान JIT (जस्ट इन टाइम) कंपाइलर नामक एक अन्य कंपाइलर IL को वास्तविक मशीन कोड में बदल देता है जो निष्पादित कर सकता है।

तो पहले इस प्रश्न का उत्तर दें कि "MSIL आखिर क्यों है?" सिर्फ C # कंपाइलर को मशीन कोड क्यों नहीं लिखा जाना चाहिए?

क्योंकि यह इस तरह से करना सस्ता है। मान लीजिए हमने ऐसा नहीं किया; मान लें कि प्रत्येक भाषा का अपना मशीन कोड जनरेटर होना चाहिए। आपके पास बीस अलग-अलग भाषाएँ हैं: C #, JScript .NET , Visual Basic, IronPython , F # ... और मान लीजिए कि आपके पास दस अन्य प्रोसेसर हैं। आपको कितने कोड जनरेटर लिखने होंगे? 20 x 10 = 200 कोड जनरेटर। वह बहुत काम की चीज है। अब मान लीजिए कि आप एक नया प्रोसेसर जोड़ना चाहते हैं। आपको इसके लिए कोड जनरेटर को बीस बार लिखना होगा, प्रत्येक भाषा के लिए एक।

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

अब मान लीजिए कि हम इसे CIL तरीके से करते हैं। आपको कितने CIL जनरेटर लिखने हैं? एक प्रति भाषा। आपको कितने JIT कंपाइलर लिखने हैं? एक प्रति प्रोसेसर। कुल: 20 + 10 = 30 कोड जनरेटर। इसके अलावा, भाषा से सीआईएल जनरेटर लिखना आसान है क्योंकि सीआईएल एक सरल भाषा है, और सीआईएल-टू-मशीन-कोड जनरेटर भी लिखना आसान है क्योंकि सीआईएल एक सरल भाषा है। हम C # और VB की सभी पेचीदगियों से छुटकारा पा लेते हैं और व्हाट्सएप और "लोअर" सब कुछ एक सरल भाषा में करते हैं जिसके लिए एक घबराना लिखना आसान है।

एक मध्यवर्ती भाषा होने से एक नई भाषा संकलक के उत्पादन की लागत नाटकीय रूप से कम हो जाती है । यह नाटकीय रूप से एक नई चिप का समर्थन करने की लागत को कम करता है। आप एक नई चिप का समर्थन करना चाहते हैं, आप उस चिप पर कुछ विशेषज्ञों को ढूंढते हैं और उन्हें एक सीआईएल घबराना लिखते हैं और आपका काम हो जाता है; फिर आप अपनी चिप पर उन सभी भाषाओं का समर्थन करते हैं।

ठीक है, इसलिए हमने स्थापित किया है कि हमारे पास एमएसआईएल क्यों है; क्योंकि एक मध्यवर्ती भाषा होने से लागत कम होती है। फिर भाषा "स्टैक मशीन" क्यों है?

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

आप पूछते हैं "आखिर एक स्टैक क्यों है?" क्यों नहीं सब कुछ सीधे स्मृति से बाहर है? खैर, चलिए इसके बारे में सोचते हैं। मान लीजिए कि आप CIL कोड जनरेट करना चाहते हैं:

int x = A() + B() + C() + 10;

मान लीजिए कि हमारे पास यह कन्वेंशन है कि "ऐड", "कॉल", "स्टोर" और इसी तरह हमेशा स्टैक से अपने तर्क लें और स्टैक पर अपना परिणाम (यदि कोई है) डाल दें। इस C # के लिए CIL कोड जनरेट करने के लिए हम ऐसा कुछ कहते हैं:

load the address of x // The stack now contains address of x
call A()              // The stack contains address of x and result of A()
call B()              // Address of x, result of A(), result of B()
add                   // Address of x, result of A() + B()
call C()              // Address of x, result of A() + B(), result of C()
add                   // Address of x, result of A() + B() + C()
load 10               // Address of x, result of A() + B() + C(), 10
add                   // Address of x, result of A() + B() + C() + 10
store in address      // The result is now stored in x, and the stack is empty.

अब मान लीजिए कि हमने इसे बिना स्टैक के किया। हम इसे आपके तरीके से करेंगे, जहाँ हर ओपकोड अपने ऑपरेंड्स के पते लेता है और जिस पते पर वह अपना रिजल्ट स्टोर करता है :

Allocate temporary store T1 for result of A()
Call A() with the address of T1
Allocate temporary store T2 for result of B()
Call B() with the address of T2
Allocate temporary store T3 for the result of the first addition
Add contents of T1 to T2, then store the result into the address of T3
Allocate temporary store T4 for the result of C()
Call C() with the address of T4
Allocate temporary store T5 for result of the second addition
...

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

हम स्टैक-आधारित ऑपकोड का उपयोग करते हैं क्योंकि स्टैक सामान्य समस्या को हल करते हैं । अर्थात्: मैं कुछ अस्थायी भंडारण आवंटित करना चाहता हूं, बहुत जल्द इसका उपयोग करूंगा और जब मैं पूरा कर लूंगा, तो इससे जल्दी छुटकारा पा लूंगा । यह अनुमान लगाकर कि हमारे पास हमारे निपटान में एक स्टैक है, हम opcodes को बहुत छोटा बना सकते हैं और कोड बहुत ही जटिल है।

अद्यतन: कुछ अतिरिक्त विचार

संयोग से, (1) एक वर्चुअल मशीन, (2) लेखन कंपाइलर्स, जो VM भाषा को लक्षित करते हैं, और (3) विभिन्न प्रकार के हार्डवेयर पर VM का कार्यान्वयन लागू करते हैं, (1) को कम करने का यह विचार एक नया विचार नहीं है। । इसकी उत्पत्ति MSIL, LLVM, Java bytecode, या किसी अन्य आधुनिक अवसंरचना से नहीं हुई थी। इस रणनीति का सबसे पहला कार्यान्वयन मुझे पता है कि 1966 से पीसीओडी मशीन है।

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


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

18
यह बहुत अच्छा जवाब था। मुझे याद दिलाता है कि मैं जावा ब्लॉग होने के बावजूद आपका ब्लॉग क्यों पढ़ता हूं। ;-)
जेपर्ट

34
@JanCarloViray: आपका बहुत बहुत स्वागत है! मैं ध्यान दें कि मैं कर रहा हूँ एक प्रधान डेवलपर, नहीं प्रिंसिपल डेवलपर। इस जॉब टाइटल वाली टीम में कई लोग हैं और मैं उनमें से सबसे वरिष्ठ भी नहीं हूं।
एरिक लिपर्ट

17
@ ईरिक: यदि / जब आप कभी भी प्यार करना बंद कर देते हैं, तो आपको प्रोग्रामर को पढ़ाने पर विचार करना चाहिए। मज़े के अलावा, आप व्यवसाय के दबाव के बिना एक हत्या कर सकते हैं। बहुत बढ़िया स्वभाव है जो आपको उस क्षेत्र में मिला है (और अद्भुत धैर्य, मैं जोड़ सकता हूं)। मैं कहता हूं कि एक पूर्व विश्वविद्यालय व्याख्याता के रूप में।
एलन

19
मेरे बारे में 4 पैराग्राफ मेरे स्वयं के लिए कह रहे थे "यह एरिक की तरह लगता है", 5 वीं या 6 वीं मैं "हां, निश्चित रूप से एरिक" के लिए स्नातक किया जाएगा :) एक और सही मायने में और व्यापक रूप से व्यापक जवाब।
बाइनरी वॉरियर

86

ध्यान रखें कि जब आप MSIL के बारे में बात कर रहे होते हैं तब आप वर्चुअल मशीन के निर्देशों के बारे में बात कर रहे होते हैं । .NET में इस्तेमाल किया गया VM एक स्टैक आधारित वर्चुअल मशीन है। एक रजिस्टर आधारित वीएम के विरोध के रूप में, एंड्रॉइड ऑपरेटिंग सिस्टम में उपयोग किया जाने वाला Dalvik VM इसका एक उदाहरण है।

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

वास्तविक मशीन कोड मॉडल मिश्रित है, जिसमें एक स्टैक और रजिस्टर दोनों हैं। JIT कोड ऑप्टिमाइज़र की बड़ी नौकरियों में से एक है, रजिस्टरों में स्टैक पर रखे गए वैरिएबल को स्टोर करने के तरीकों के साथ आना, जिससे निष्पादन की गति में काफी सुधार होता है। एक Dalvik घबराना विपरीत समस्या है।

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


2
एक बहुत विस्तृत विवरण के लिए +1, और अन्य प्रणालियों और भाषा की तुलना में अतिरिक्त विस्तृत के लिए +100 (अगर मैं कर सकता था) :)
जन कार्लो वीर

4
Dalvik एक रजिस्टर मशीन क्यों है? सिसिली अपने मुख्य रूप से एआरएम प्रोसेसर पर लक्षित है। अब, x86 में रजिस्टरों की समान मात्रा है, लेकिन CISC होने के नाते, उनमें से केवल 4 स्थानीय लोगों को संग्रहीत करने के लिए वास्तव में उपयोग करने योग्य हैं, क्योंकि बाकी का उपयोग सामान्य निर्देशों में किया गया है। दूसरी ओर एआरएम आर्किटेक्चर के पास बहुत अधिक रजिस्टर हैं जिनका उपयोग स्थानीय लोगों को संग्रहीत करने के लिए किया जा सकता है, इसलिए वे एक रजिस्टर आधारित निष्पादन मॉडल की सुविधा प्रदान करते हैं।
जोहान्स रूडोल्फ

1
@JohannesRudolph यह लगभग दो दशकों से सच नहीं है। सिर्फ इसलिए कि अधिकांश C ++ कंपाइलर अभी भी 90s x86 के निर्देश को लक्षित करते हैं सेट का मतलब यह नहीं है कि x86 ही कुशल है। हैसवेल में 168 सामान्य उद्देश्य पूर्णांक रजिस्टर और 168 जीपी एवीएक्स रजिस्टर हैं, उदाहरण के लिए - किसी भी एआरएम सीपीयू की तुलना में कहीं अधिक जो मुझे पता है। आप (आधुनिक) x86 असेंबली से उन सभी का उपयोग कर सकते हैं जो आप चाहते हैं। कंपाइलर लेखकों को दोष दें, न कि आर्किटेक्चर / सीपीयू को। वास्तव में, यह एक कारण है कि मध्यवर्ती संकलन इतना आकर्षक क्यों है - एक बाइनरी, किसी दिए गए सीपीयू के लिए सबसे अच्छा कोड; 90 के दशक की स्थापत्य कला के साथ कोई मूकदर्शक नहीं।
लुआॅन

2
@JohannesRudolph। NET JIT कंपाइलर वास्तव में रजिस्टरों का काफी उपयोग करता है; स्टैक ज्यादातर आईएल आभासी मशीन का एक अमूर्त हिस्सा है, कोड जो वास्तव में आपके सीपीयू पर चलता है, बहुत अलग है। विधि कॉल पास-पास रजिस्टर हो सकता है, स्थानीय लोगों को रजिस्टरों के लिए उठाया जा सकता है ... मशीन कोड में स्टैक का मुख्य लाभ यह अलगाव है जो इसे सबरूटीन कॉल को देता है - यदि आप एक रजिस्टर में एक स्थानीय डालते हैं, तो एक फ़ंक्शन कॉल हो सकती है आप उस मूल्य को खो देते हैं, और आप वास्तव में नहीं बता सकते।
लुआॅन

1
@RahulAgarwal उत्पन्न मशीन कोड किसी भी स्थानीय या मध्यवर्ती मूल्य के लिए स्टैक का उपयोग कर सकता है या नहीं भी कर सकता है। IL में, प्रत्येक तर्क और स्थानीय स्टैक पर है - लेकिन मशीन कोड में, यह सच नहीं है (यह अनुमति है, लेकिन आवश्यक नहीं है)। कुछ चीजें स्टैक पर उपयोगी होती हैं, और वे स्टैक पर डाल दी जाती हैं। कुछ चीजें ढेर पर उपयोगी होती हैं, और वे ढेर पर रख दी जाती हैं। कुछ चीजें बिल्कुल भी आवश्यक नहीं होती हैं, या केवल एक रजिस्टर में कुछ क्षणों की आवश्यकता होती है। कॉल को पूरी तरह से (इनलाइन) समाप्त किया जा सकता है, या उनके तर्कों को रजिस्टरों में पारित किया जा सकता है। JIT में बहुत स्वतंत्रता है।
लुआण

20

इस पर एक बहुत ही रोचक / विस्तृत विकिपीडिया लेख है, स्टैक मशीन के निर्देश सेट के फायदे । मुझे इसे पूरी तरह से उद्धृत करने की आवश्यकता होगी, इसलिए केवल एक लिंक डालना आसान है। मैं बस उप-शीर्षक उद्धृत करूंगा

  • बहुत कॉम्पैक्ट ऑब्जेक्ट कोड
  • सरल संकलक / सरल व्याख्याकार
  • न्यूनतम प्रोसेसर स्थिति

-1 @xanatos क्या आप अपने द्वारा लिए गए शीर्षकों को आजमा सकते हैं और संक्षेप में बता सकते हैं?
टिम लॉयड

@chibacity अगर मैं उन्हें संक्षेप में प्रस्तुत करना चाहता, तो मैं एक उत्तर देता। मैं एक बहुत अच्छी कड़ी को उबारने की कोशिश कर रहा था।
xanatos

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

@chibacity ओपी शायद पहले न खोज पाने में आलसी था। यहाँ उत्तर देने वाले ने एक अच्छा लिंक दिया (बिना बताए)। दो बुराइयाँ एक अच्छा करती हैं :-) और मैं हंस को उभार दूंगा।
xanatos

एक महान लिंक के लिए उत्तर देने वाले और @xanatos +1 के लिए। मैं किसी के लिए पूरी तरह से सारांशित करने और ज्ञान-पैक जवाब देने के लिए इंतजार कर रहा था .. अगर हंस ने जवाब नहीं दिया, तो मैंने आपका जवाब स्वीकार कर लिया होगा .. यह सिर्फ एक लिंक था, इसलिए यह नहीं था हेंस के लिए निष्पक्ष जिन्होंने अपने उत्तर पर एक अच्छा प्रयास रखा .. :)
जन कार्लो विरय

8

स्टैक प्रश्न के लिए थोड़ा और जोड़ने के लिए। स्टैक अवधारणा सीपीयू डिज़ाइन से निकलती है जहाँ अंकगणितीय तर्क इकाई (ALU) में मशीन कोड ऑपरेशंस पर संचालित होता है जो स्टैक पर स्थित होते हैं। उदाहरण के लिए एक मल्टीपल ऑपरेशन स्टैक से दो शीर्ष ऑपरेंड ले सकता है, कई उन्हें और परिणाम को स्टैक पर वापस रखता है। मशीन भाषा में आमतौर पर स्टैक से ऑपरेंड को जोड़ने और हटाने के दो बुनियादी कार्य होते हैं; PUSH और POP। कई सीपीयू के डीएसपी (डिजिटल सिग्नल प्रोसेसर) और मशीन नियंत्रकों (जैसे कि वाशिंग मशीन को नियंत्रित करना) में स्टैक चिप पर ही स्थित होता है। यह ALU को अधिक तेज़ गति प्रदान करता है और आवश्यक कार्यक्षमता को एक चिप में समेकित करता है।


5

यदि स्टैक / हीप की अवधारणा का पालन नहीं किया जाता है और डेटा को रैंडम मेमोरी लोकेशन पर लोड किया जाता है या डेटा को रेंडम मेमोरी लोकेशन से स्टोर किया जाता है ... तो यह बहुत ही अनस्ट्रक्चर्ड और अनवांटेड होगा।

इन अवधारणाओं का उपयोग प्रदर्शन, मेमोरी उपयोग ... और इसलिए डेटा संरचनाओं को सुधारने के लिए पूर्वनिर्धारित संरचना में डेटा को संग्रहीत करने के लिए किया जाता है।


4

कोडिंग को जारी रखने की शैली का उपयोग करके, स्टैक के बिना काम करने वाला एक सिस्टम हो सकता है । फिर कॉल फ़्रेम एकत्र किए गए कचरे में आवंटित निरंतरता बन जाते हैं (कचरा कलेक्टर को कुछ स्टैक की आवश्यकता होगी)।

एंड्रयू एपेल का पुराना लेखन देखें: निरंतरता और कचरा संग्रह के साथ संकलन स्टैक आवंटन की तुलना में तेज हो सकता है

(वह कैश की समस्या के कारण आज थोड़ा गलत हो सकता है)


0

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

स्टैक-आधारित भाषाओं का एक परिवार भी है जिसे संघात्मक भाषाएं कहा जाता है । वे सभी (मुझे विश्वास है) कार्यात्मक भाषाएं हैं, क्योंकि स्टैक एक अंतर्निहित पैरामीटर पास-इन है, और परिवर्तित स्टैक प्रत्येक फ़ंक्शन से एक अंतर्निहित वापसी भी है। फोर्थ और फैक्टर (जो उत्कृष्ट है) दोनों अन्य के साथ उदाहरण हैं। लुका के समान फैक्टर का उपयोग स्क्रिप्टिंग गेम्स के लिए किया गया है, और स्लाव पेस्टोव द्वारा लिखा गया था, जो वर्तमान में ऐप्पल में काम कर रहा है। यूट्यूब पर उनका Google TechTalk मैंने कुछ बार देखा है। वह बोआ कंस्ट्रक्टर के बारे में बात करते हैं, लेकिन मुझे यकीन नहीं है कि उनका क्या मतलब है ;-)।

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

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

ईज़ी पर आसान , जावास्क्रिप्ट में लिखा गया एक अच्छा ऑनलाइन ट्यूटोरियल, यहाँ एक छोटा सा नमूना है (शून्य-बिंदु कॉलिंग शैली के उदाहरण के रूप में "वर्गमूल वर्ग" पर ध्यान दें):

: sq dup * ;  ok
2 sq . 4  ok
: ^4 sq sq ;  ok
2 ^4 . 16  ok
: ^8 sq sq sq sq ;  ok
2 ^8 . 65536  ok

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

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

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

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