2008-10-13 24 views
9

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

सिस्टम पर चलने वाले प्रत्येक धागे के लिए ढेर बनाने के लिए एक अच्छा आकार क्या है? क्या मुझे सिस्टम को इस तरह से डिजाइन करने की कोशिश करनी चाहिए कि अधिकतम लंबाई तक पहुंचने पर स्टैक को स्वचालित रूप से बढ़ाया जा सके?

मुझे लगता है कि अगर मुझे सही याद है कि रैम का एक पृष्ठ 4k या 4096 बाइट है और यह मेरे लिए बहुत कुछ नहीं लगता है। मैं निश्चित रूप से समय देख सकता हूं, खासकर जब कई रिकर्सन का उपयोग करते हैं, तो मैं एक बार में रैम में 1000 से अधिक इंटीग्रर्स रखना चाहता हूं। अब, असली समाधान यह होगा कि कार्यक्रम malloc का उपयोग कर ऐसा कर रहा है और अपने स्वयं के मेमोरी संसाधनों का प्रबंधन कर रहा है, लेकिन वास्तव में मैं इस पर उपयोगकर्ता की राय जानना चाहता हूं।

आधुनिक कंप्यूटर प्रोग्राम के साथ एक ढेर के लिए 4k बड़ा है? क्या ढेर उस से बड़ा होना चाहिए? क्या किसी भी प्रकार के आकार को समायोजित करने के लिए स्टैक ऑटो-विस्तार करना चाहिए? मुझे व्यावहारिक डेवलपर के दृष्टिकोण और एक सुरक्षा दृष्टिकोण से दोनों में दिलचस्पी है।

एक स्टैक के लिए 4k बहुत बड़ा है? सामान्य कार्यक्रम निष्पादन को ध्यान में रखते हुए, विशेष रूप से सी ++ में कक्षाओं के दृष्टिकोण से, मुझे लगता है कि अच्छे स्रोत कोड malloc/new को कक्षाओं के निर्माण के दौरान आवश्यक डेटा को फ़ंक्शन कॉल में चारों ओर फेंकने वाले डेटा को कम करने के लिए जाता है।

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

उत्तर

10

ढेर का आकार आपके धागे क्या कर रहा है इस पर निर्भर करता है। मेरी सलाह:

  • ढेर आकार धागा निर्माण के समय में एक पैरामीटर (अलग धागे अलग बातें करना होगा, और इसलिए अलग ढेर आकार की आवश्यकता होगी)
  • जो लोग नहीं करना चाहती के लिए एक उचित डिफ़ॉल्ट प्रदान करना (ढेर-अपव्ययी, करने के लिए एर, संकेत मिलता है बहुत शीघ्र, मुझ में नियंत्रण सनकी करने के लिए 4K अपील के रूप में यह कारण होगा)
  • पर विचार आप कैसे पता लगाने और ढेर अतिप्रवाह के साथ सौदा होगा एक ढेर आकार को निर्दिष्ट से परेशान होना। पता लगाना मुश्किल हो सकता है। आप अपने स्टैक के सिरों पर गार्ड पेज - खाली रख सकते हैं, और यह आम तौर पर काम करेगा। लेकिन आप खराब थ्रेड के व्यवहार पर भरोसा कर रहे हैं कि उस घास पर छलांग लगाने के लिए और आगे बढ़ने के लिए प्रदूषण शुरू करें। आम तौर पर ऐसा नहीं होगा ... लेकिन फिर, यही कारण है कि वास्तव में कठिन बग कठिन बनाते हैं। एक एयरटाइट तंत्र में स्टैक चेकिंग कोड उत्पन्न करने के लिए आपके कंपाइलर को हैकिंग करना शामिल है। एक स्टैक ओवरफ़्लो से निपटने के लिए, आपको किसी अन्य जगह पर एक समर्पित स्टैक की आवश्यकता होगी जिस पर आपत्तिजनक धागा (या इसके अभिभावक परी, जो भी आप तय करते हैं - आप ओएस डिजाइनर हैं) सभी चलेंगे।
  • मैं दृढ़ता से, एक विशिष्ट पैटर्न के साथ अपने ढेर के सिरों अंकन की सलाह देते हैं, ताकि जब आपके धागे सिरों पर चलाया (और वे हमेशा करते हैं), आप कम से कम पोस्टमार्टम में जाना और देखते हैं कि कुछ वास्तव में किया था कर सकते हैं अपने ढेर से भागो। 0xDEADBEEF का एक पृष्ठ या ऐसा कुछ आसान है।

वैसे, x86 पृष्ठ आकार आमतौर पर 4k होते हैं, लेकिन उन्हें होने की आवश्यकता नहीं होती है। आप 64k आकार या इससे भी बड़े के साथ जा सकते हैं। बड़े पृष्ठों के लिए सामान्य कारण टीएलबी मिस से बचने के लिए है। दोबारा, मैं इसे कर्नेल कॉन्फ़िगरेशन या रन-टाइम पैरामीटर बना दूंगा।

+0

मैंने कभी संकलन समय पर कॉन्फ़िगर करने के लिए कुछ करने के बारे में सोचा नहीं। मैं भी 4k की तरह लगता है, नियंत्रण सनकी मुझसे कहता है कि यदि आप वास्तव में है कि अधिक स्मृति की तुलना में अधिक उपयोग करने की आवश्यकता है, तो आप malloc के साथ यह कर होना चाहिए।^_^उस ने कहा, वहाँ पागल एआई प्रोग्रामर हैं जो उनके रिकर्सन से प्यार करते हैं। –

+0

यदि आप एक ही आकार की चीज़ को बार-बार आवंटित कर रहे हैं, तो आपको एक निश्चित-ब्लॉक आवंटक पर विचार करना चाहिए। यह सामान्य उद्देश्य मॉलोक से कहीं अधिक कुशल हो सकता है। – bog

0

स्टैक आकार को कॉन्फ़िगर करने योग्य आइटम क्यों नहीं बनाते हैं, या तो प्रोग्राम के साथ संग्रहीत किया जाता है या निर्दिष्ट किया जाता है जब कोई प्रक्रिया दूसरी प्रक्रिया बनाती है?

इस कॉन्फ़िगर करने योग्य तरीके से आप कई तरीकों से कर सकते हैं।

एक दिशा-निर्देश है जो "0, 1 या n" कहता है, जिसका अर्थ है कि आपको किसी ऑब्जेक्ट के शून्य, एक या किसी भी संख्या (स्मृति जैसी अन्य बाधाओं द्वारा सीमित) की अनुमति देनी चाहिए - यह ऑब्जेक्ट्स के आकारों पर भी लागू होती है।

1

मैं गेंद रोलिंग प्राप्त करने के लिए मेरी दो सेंट फेंक देंगे:

  • मुझे यकीन है कि क्या एक "विशिष्ट" ढेर आकार होगा नहीं हूँ। मुझे लगता है कि प्रति थ्रेड 8 KB हो सकता है, और यदि कोई धागा इस राशि से अधिक है, तो बस एक अपवाद फेंक दें। हालांकि, this के अनुसार, विंडोज धागा प्रति 1 एमबी की एक डिफ़ॉल्ट सुरक्षित ढेर आकार है, लेकिन यह एक बार में सभी (पृष्ठों के रूप में वे की जरूरत है के लिए प्रतिबद्ध हैं) प्रतिबद्ध नहीं है। इसके अतिरिक्त, आप कंपाइलर निर्देश के साथ संकलित समय पर दिए गए EXE के लिए एक अलग स्टैक आकार का अनुरोध कर सकते हैं। सुनिश्चित नहीं है कि लिनक्स क्या करता है, लेकिन मैंने 4 केबी स्टैक्स के संदर्भ देखे हैं (हालांकि मुझे लगता है कि जब आप कर्नेल संकलित करते हैं तो यह बदला जा सकता है और मुझे यकीन नहीं है कि डिफ़ॉल्ट स्टैक आकार क्या है ...)

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

1

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

यदि आप स्टैक आकार को नियंत्रित करने का कोई तरीका चाहते हैं और आपका लक्ष्य वास्तव में नियंत्रित और कुशल वातावरण है, लेकिन लिनक्स इत्यादि के समान शैली में प्रोग्रामिंग की परवाह नहीं है, तो एक सिंगल शॉट निष्पादन मॉडल के लिए जाएं जहां एक कार्य हर बार एक प्रासंगिक घटना का पता चला है, पूरा होने के लिए चलाता है, और फिर अपने कार्य डेटा संरचना में किसी भी लगातार डेटा स्टोर करता है। इस तरह, सभी धागे एक ही ढेर साझा कर सकते हैं। ऑटोमोटिव नियंत्रण और इसी तरह के लिए कई पतली रीयल-टाइम ऑपरेटिंग सिस्टम में प्रयुक्त होता है।

+0

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

2

लिनक्स कर्नेल स्रोत कोड में KERNEL_STACK_SIZE के लिए खोजें और आप पाएंगे कि यह बहुत अधिक आर्किटेक्चर निर्भर है - PAGE_SIZE, या 2 * PAGE_SIZE आदि (नीचे केवल कुछ परिणाम हैं - कई मध्यवर्ती आउटपुट हटा दिए जाते हैं)।

./arch/cris/include/asm/processor.h: 
#define KERNEL_STACK_SIZE PAGE_SIZE 

./arch/ia64/include/asm/ptrace.h: 
# define KERNEL_STACK_SIZE_ORDER  3 
# define KERNEL_STACK_SIZE_ORDER  2 
# define KERNEL_STACK_SIZE_ORDER  1 
# define KERNEL_STACK_SIZE_ORDER  0 
#define IA64_STK_OFFSET   ((1 << KERNEL_STACK_SIZE_ORDER)*PAGE_SIZE) 
#define KERNEL_STACK_SIZE  IA64_STK_OFFSET 

./arch/ia64/include/asm/mca.h: 
    u64 mca_stack[KERNEL_STACK_SIZE/8]; 
    u64 init_stack[KERNEL_STACK_SIZE/8]; 

./arch/ia64/include/asm/thread_info.h: 
#define THREAD_SIZE   KERNEL_STACK_SIZE 

./arch/ia64/include/asm/mca_asm.h: 
#define MCA_PT_REGS_OFFSET  ALIGN16(KERNEL_STACK_SIZE-IA64_PT_REGS_SIZE) 

./arch/parisc/include/asm/processor.h: 
#define KERNEL_STACK_SIZE (4*PAGE_SIZE) 

./arch/xtensa/include/asm/ptrace.h: 
#define KERNEL_STACK_SIZE (2 * PAGE_SIZE) 

./arch/microblaze/include/asm/processor.h: 
# define KERNEL_STACK_SIZE 0x2000