2015-10-07 10 views
6

मैं सीयूडीए और बार्न्स-हट एल्गोरिदम के बारे में एक वीडियो देख रहा था जहां यह कहा गया था कि जीपीयू के लिए पेड़ पर गहराई सीमा रखना आवश्यक है, और फिर विचार संभवतः मेरे सिर में चले गए ढेर में रिकर्सन कर रहे हैं।मेमोरी आवंटन के साथ रिकर्सन

असल में, मैं सिर्फ इतना है कि सोच रहा हूँ: ढेर से स्मृति को आबंटित और उपयोग करने के लिए क्या यह संभव है कि एक अस्थायी "ढेर" जिसमें समारोह सवाल में पुनरावर्ती क्रिया को कुछ हद तक एक ढेर अतिप्रवाह में देरी करने के लिए कॉल करने के रूप में?

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

[संपादित करें] मैं सिर्फ यह जोड़ना चाहता था कि यह पूरी तरह सैद्धांतिक प्रश्न है, और मुझे लगता है कि ऐसा करने से प्रोग्राम ढेर का उपयोग कर धीमा हो जाएगा।

[संपादित करें] अनुरोध के अनुसार, संकलक मैं उपयोग कर रहा हूँ Ubuntu 14.04 (64-बिट)

+2

सी ऐसी किसी भी तंत्र को परिभाषित नहीं करता है। वास्तव में, यह उन या किसी अन्य नाम के तहत "ढेर" या "ढेर" को परिभाषित नहीं करता है। वे अधिकांश * कार्यान्वयन * के पहलुओं के लिए मानक नाम हैं, लेकिन वे सी के दायरे से बाहर हैं। एक तरफ, इसका मतलब है कि आपको उपयोगी उत्तर प्राप्त करने के लिए एक विशेष कार्यान्वयन निर्दिष्ट करना होगा। दूसरी ओर, इसका यह भी अर्थ है कि सी स्वयं जो वर्णन करता है उसे मना नहीं करता है। तीसरे हाथ पर, मुझे किसी भी कार्यान्वयन से अवगत नहीं है जो इसे प्रदान करता है। –

+0

@ जॉन बोलिंगर क्षमा करें, मुझे यह कहने का मतलब नहीं है कि मुझे एक विशेष कार्यान्वयन निर्दिष्ट करने की आवश्यकता होगी। क्या आपका मतलब है कि भाषा ही स्मृति के साथ कैसे व्यवहार करती है? मैंने अभी तक कुछ प्रारंभिक पाठ्यक्रमों को लिया है और सी संकलक (और मुझे लगता है कि अधिकांश कंपाइलर) स्मृति को प्रबंधित करने के मूलभूत बातों के अलावा अन्य चीजों के इस पक्ष में नहीं पहुंच पाए हैं। – Plopperzz

+0

"एक विशेष कार्यान्वयन निर्दिष्ट करना" का मतलब है कि प्रश्न के दायरे को लिनक्स पर जीसीसी 5/ग्लिबिक, या विंडोज 10 पर एमएस विजुअल सी ++ 2013 जैसे कुछ को सीमित करना है। –

उत्तर

3

ज़रूर पर जीसीसी 4.8.4 है। इसे निरंतरता-गुजरने वाली शैली कहा जाता है। मानक लाइब्रेरी setjmp() और longjmp() के साथ इसका समर्थन करती है, और jmp_buf नामक संरचना में पहले बिंदु पर नियंत्रण बहाल करने के लिए आवश्यक जानकारी संग्रहीत करती है। (आप कहां से बहाल कर सकते हैं पर कई प्रतिबंध हैं।) आप उन्हें एक ढेर में स्टोर करेंगे, जो सिर्फ एक लिफो कतार है।

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

निरंतरता-गुजरने और ट्रैम्पोलिन को फैंसी शैली के रूप में माना जाता है क्योंकि वे कार्यात्मक प्रोग्रामिंग की दुनिया से आते हैं, जबकि longjmp() को बदसूरत निम्न-स्तरीय हैक के रूप में माना जाता है और यहां तक ​​कि लिनक्स मैन पेज का उपयोग नहीं करना है।

+0

मुझे नहीं लगता कि निरंतरता वास्तव में प्रश्न को संबोधित करते हैं, क्योंकि वे बाद में कॉल के लिए सिस्टम के उपयोग के लिए क्या उपयोग नहीं करते हैं, न तो सीधे कोड में और न ही निरंतरता में। यदि एक निरंतरता वांछित है, तो यह ध्यान रखना महत्वपूर्ण है कि 'setjmp() '/' longjmp()' केवल सीमित तरीके से उनका समर्थन करता है, क्योंकि एक बार नियंत्रण 'setjmp()' नामक फ़ंक्शन को छोड़ देता है, एक संबंधित longjmp का व्यवहार अब परिभाषित नहीं किया गया है। –

+0

यह फ़ंक्शन कॉल और रिटर्न से नियंत्रण प्रवाह का वैकल्पिक माध्यम है। उस ने कहा, 'longjmp()' के बारे में आपकी टिप्पणी सही नहीं है: यदि मूल कार्य * बाहर निकला है, तो व्यवहार अपरिभाषित है * जैसे ही नियंत्रण इसे छोड़ देता है। 'Setjmp()' नामक एक व्यक्ति द्वारा रिकर्सली नामक फ़ंक्शन से 'longjmp() 'के लिए कानूनी है। असल में, वह उपयोग का मामला था जिसके लिए 'गोटो' पर्याप्त नहीं था। – Davislor

+1

"नियंत्रण पत्तियों" से मेरा मतलब था कि फ़ंक्शन कॉलिंग (अन्य) फ़ंक्शंस के विपरीत, 'longjmp()' को कॉल करके लौटता है या बाहर निकलता है। वैसे भी, ओपी का सवाल विशेष रूप से कॉल स्टैक के लिए स्मृति के एक अलग क्षेत्र का उपयोग करने के बारे में है। चूंकि निरंतरताएं * वैकल्पिक * कॉल/वापसी के लिए होती हैं, इसी कारण से वे प्रश्न का समाधान नहीं करते हैं। –

1

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

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

यह कुछ देखभाल करता है, तो ढेर फ्रेम संरचना एम्बेडेड संकेत होता है के लिए आवश्यक है, लेकिन इसे दुर्गम नहीं है।

संबंधित मुद्दे