2009-05-20 6 views
5

यदि प्रति ऑब्जेक्ट प्रारंभिक मेमोरी आवंटन का गुच्छा है तो मैं बहुत सी सिमुलेशन चला रहा हूं। अनुकरण को जितनी जल्दी हो सके चलाना है, लेकिन आवंटन की गति महत्वपूर्ण नहीं है। मैं deallocation से चिंतित नहीं हूँ।क्या सी ++ के लिए कोई अच्छा कस्टम आवंटक है जो संदर्भ के इलाके को अधिकतम करता है?

आदर्श रूप से, आवंटक स्मृति के एक समान ब्लॉक में सबकुछ रखेगा। (मुझे लगता है कि इसे कभी-कभी क्षेत्र कहा जाता है?)

मैं एक चपटे वेक्टर का उपयोग करने में सक्षम नहीं हूं क्योंकि आवंटित वस्तुएं पॉलिमॉर्फिक हैं।

मेरे विकल्प क्या हैं?

उत्तर

5

बस अपना खुद का बनाओ।

को देखने के लिए आप कैसे शुरू कर सकते हैं मेरा एक पुराने प्रश्न देखें:

Improvements for this C++ stack allocator?

+0

यह एक अच्छी शुरुआत है। धन्यवाद। क्या आपने कभी deallocate() लिखा था? –

+0

क्या आपने कभी संरेखण के मुद्दों को ठीक किया है? सिस्टम के आवश्यक आवश्यक संरेखण को आप कैसे प्राप्त करते हैं? –

+0

@Neil, नहीं, मैंने deallocate समाप्त नहीं किया है, लेकिन अगर यह सभी पीओडीएस है, या इसे अनुक्रमिक रूप से चलना बहुत आसान है, तो इसे अनुक्रमिक रूप से चलना बहुत आसान है। संरेखण मुद्दे के लिए, यह x86 के लिए कोई मुद्दा नहीं है। यदि यह है, तो बस निकटतम 16 बाइट संरेखण के लिए गोल करें। – Unknown

1

सामान्य तकनीक निश्चित ब्लॉक आवंटन है। देखें: Lea, Robinson, Knowlton, Grunwald

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

यदि आप पहले से नहीं जानते कि ऑब्जेक्ट की सामग्री कितनी बड़ी होगी, तो आप एक पूलिंग आवंटक लिख सकते हैं जो क्रमशः स्मृति आवंटित करता है; यानी, यह

Foo *a = new Foo(); 
Bar *b = new Bar; 
b == ((byte *)(a)) + sizeof(Foo); 

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

+0

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

+0

हम संदर्भ के इलाके पाने के लिए उनका उपयोग करते हैं (कैश आर्किटेक्चर पर जीवन है जो मैं सौदा करता हूं); स्पष्ट रूप से यह बेहतर काम करता है यदि आप अक्सर ऑब्जेक्ट्स को डिलीकेट नहीं कर रहे हैं। यदि आपको आवश्यकता हो तो आप अंतराल पर पूल में वस्तुओं को डिफ्रैगमेंट भी कर सकते हैं। – Crashworks

+0

आप संरेखण से कैसे निपटते हैं? –

0

यह एक बहुत बड़ा विषय है, बस wikipedia पर लें। एक ठोस उदाहरण अलेक्जेंड्रेस्कू पुस्तक में था और उसे Loki library में कार्यान्वित किया जाना चाहिए। जीसीसी भी std::allocator के कई कार्यान्वयन के साथ आता है, बस अपने वितरण में देखें।

1

Fixed-Size Block Allocator suite काफी अच्छी तरह से काम करता है, और यह बहुत ही आकर्षक लाइसेंस प्राप्त (एमआईटी) है।

4

के बारे में जब से तुम को डी-आवंटन के बारे में परवाह नहीं है आप एक रेखीय संभाजक उपयोग कर सकते हैं। शुरुआत में एक बड़ी मात्रा में स्मृति आवंटित करें और शुरुआत में एक सूचक को स्टोर करें। malloc (x) आवंटन पॉइंटर को x बाइट्स द्वारा आगे बढ़ाता है और पॉइंटर का पुराना मान देता है, हटाएं (x) दबाया जाता है। जैसा कि यहां बताया गया है, एक और पोस्टर में पहले से ही an implimentation

आवंटन जितना संभव हो सके पैक किया जाता है, आवंटन अविश्वसनीय रूप से तेज़ होते हैं और आवंटित क्रम में स्मृति लौटा दी जाती है। जब आपका सिमुलेशन पूरा हो जाता है, तो आप बस आवंटक के पॉइंटर को स्मृति की शुरुआत में रीसेट कर देते हैं और आवंटक के बाहर से किसी भी पॉइंटर्स को इसके अंदर ऑब्जेक्ट्स में साफ़ करते हैं।

पूल आवंटक एक बेहतरीन विकल्प हैं यदि आप एक ढेर से तेज़ी से वस्तुओं को हटाना चाहते हैं, लेकिन आपके डेटा को स्मृति के रूप में बंद नहीं करेंगे और तेज़ नहीं होंगे। बढ़ावा के लिए उपयोग करें: उन लोगों के लिए पूल। गेम के लिए यह एक बेहतरीन विकल्प है यदि आपके पास स्टोर करने के लिए एक्स बाइट्स हैं - एक स्तर - और आप एक ही समय में पूरी तरह से फेंकने को तैयार हैं।

एक तरफ के रूप में, यदि आप स्मृति प्रदर्शन में रुचि रखते हैं, तो What Every Programmer Should Know About Memory-PDF देखें। इसमें संदर्भ के इलाके और प्रदर्शन पर इसके प्रभाव जैसी चीजें शामिल हैं। विशेष रूप से, आप वस्तु के प्रत्येक प्रकार है कि एक साथ प्रयोग किया जाता है के लिए एक पूल बनाने, या structs की एक सरणी

+0

यह वही है जो मैं चाहता हूं, मुझे लगता है। तो, मुझे इसे खुद लिखना है। मुझे पता है कि यह "कठिन" नहीं है, लेकिन इसे स्वयं लिखना मतलब है डीबगिंग और किसी भी गलती को ढूंढना मुश्किल हो सकता है। मुझे लगता है कि मैं "अज्ञात" समाधान के साथ शुरू करूंगा, जैसा कि आपने नोट किया था। पीडीएफ के लिए धन्यवाद। –

1

डेव हैन्सन के C Interfaces and Implementations एक बहुत अच्छा क्षेत्र आधारित संभाजक शामिल सरणियों की एक struct के बजाय के रूप में अपने वस्तुओं की घोषणा कर सकते हैं। यदि स्मृति कार्य करता है, तो वस्तुओं के साथ कोई मेटाडेटा संग्रहीत नहीं होता है, और उन्हें संगत मुक्त स्थान से आवंटित किया जाता है, इसलिए यह उतना ही इलाका है जितना आप उम्मीद कर सकते हैं।

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

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