2012-03-08 29 views
7

मैंने सी ++ अनुकूलन कुकबुक पर पढ़ा है कि एसटीएल कंटेनर के लिए मानक आवंटक जैसे std :: list, std :: set, std :: multi_set, std :: map , ई std :: multi_map को अधिक प्रदर्शनकर्ता ब्लॉक आवंटक द्वारा प्रतिस्थापित किया जा सकता है।std :: नक्शा मानक आवंटन प्रदर्शन बनाम ब्लॉक आवंटक

एक ब्लॉक आवंटक में उच्च प्रदर्शन, कम विखंडन और कुशल डेटा कैशिंग है।

मुझे वेब पर FSBAllocator पाया गया है जो मानक से तेज़ होने का दावा करता है। http://warp.povusers.org/FSBAllocator/

मैं std :: नक्शे के साथ इसे करने की कोशिश की और पाया तेजी से वास्तव में हो रहा है है, लेकिन मेरे सवाल का कैसे हो सकता है एसटीएल कार्यान्वयन एक विशिष्ट संभाजक से तो धीमी हो है और एक अन्य संभाजक की खामियों क्या कर रहे हैं पोर्टेबिलिटी और मजबूती दोनों के मामले में, मानक से? मेरा कोड विभिन्न आर्किटेक्चर (Win32, osx, linux) पर संकलित होना चाहिए। क्या किसी को उस तरह के निश्चित आकार ब्लॉक आवंटक के साथ अनुभव था?

+0

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

+0

ब्लॉक आवंटक ऐसा लगता है जो मानक के रूप में छोटे ओवरहेड के साथ अनियंत्रित आकार आवंटित नहीं कर सकता है। –

उत्तर

12

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

लेकिन आखिरकार कारण है कि ब्लॉक आवंटकों को इतनी अच्छी तरह से क्यों काम करना है क्योंकि उनके पास ऐसी जानकारी है जो मानक आवंटकों के लिए मौजूद नहीं है, और उन्हें उपयोग के मामलों के बहुत व्यापक सेट को कवर करने की आवश्यकता नहीं है। उदाहरण के लिए, यदि आपने std::map< int, int >() किया है और यह 1 एमबी आवंटित किया गया है तो आपको शायद पिस किया जाएगा, लेकिन यदि आप std::map< int, int, std::less<int>, block_alloc< 1024 * 1024 > >() करते हैं तो आप इसकी अपेक्षा करेंगे। मानक आवंटकों को ब्लॉक में आवंटित नहीं किया जाता है, वे नए स्मृति के माध्यम से नए मेमोरी का अनुरोध करते हैं, बदले में नया कोई संदर्भ नहीं है। इसे मनमाने ढंग से आकार का स्मृति अनुरोध मिलता है और लौटने के लिए बाइट्स की एक समान संख्या को खोजने की आवश्यकता होती है। सबसे अधिक कार्यान्वयन यह है कि उनके पास स्मृति क्षेत्रों का एक सेट है जो वे विभिन्न गुणों का रखरखाव करते हैं (उदाहरण के लिए, 4 बाइट्स के लिए एक क्षेत्र संभवतः उपस्थित होने की गारंटी देता है, क्योंकि 4 बाइट्स के लिए अनुरोध बहुत आम हैं)। यदि कोई अनुरोध एक बहुतायत नहीं है तो अंतरिक्ष को बर्बाद किए बिना एक अच्छा हिस्सा वापस करने और विखंडन का कारण बनना मुश्किल हो जाता है। मूल रूप से मनमानी आकारों का स्मृति प्रबंधन करना बहुत कठिन होता है यदि आप इसे निरंतर समय, कम विखंडन, धागा सुरक्षित इत्यादि के करीब होना चाहते हैं

Boost pool allocator प्रलेखन में कुछ अच्छी जानकारी है कि एक अच्छा ब्लॉक आवंटक कैसे काम कर सकता है।

+0

धन्यवाद, अच्छा स्पष्टीकरण। मुझे लगता है कि मैं डिफ़ॉल्ट आवंटक का उपयोग जारी रखूंगा! मुझे एसटीएल कार्यान्वयन पर भरोसा है – linello