2012-12-03 54 views
6

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

इरादा था कि संभाजक एसटीएल और स्टैंडर्ड सी के साथ ++ ऐसे वेक्टर, Deque, नक्शे, स्ट्रिंग आदि के रूप में आधारित कंटेनर

हालांकि विशेष रूप से कुछ मुझे कुछ भ्रम उत्पन्न हुआ है संगत हो। इस तरह के std :: वेक्टर, std :: स्ट्रिंग मेकअप छोटे बफर अनुकूलन के उपयोग के रूप कंटेनरों के विभिन्न कार्यान्वयन - आधारित लघु प्रारंभिक स्मृति आवश्यकताओं के लिए आवंटन ढेर।

उदाहरण MSVC9.1 लिए basic_string कक्षा में निम्नलिखित सदस्य हैं:

union _Bxty 
{ // storage for small buffer or pointer to larger one 
    _Elem _Buf[_BUF_SIZE]; 
    _Elem *_Ptr; 
    char _Alias[_BUF_SIZE]; // to permit aliasing 
} _Bx; 

मैं नहीं देख सकते हैं कि जब इस तरह के कंटेनर instantiating एक ही करने के लिए कार्यान्वयन फुसलाना कर सकते हैं और हमेशा प्रदान की संभाजक का उपयोग और एसबीओ का उपयोग नहीं करते हैं। मैं पूछता हूं क्योंकि को लागू करने के इरादे में से एक कस्टम आवंटकों को साझा स्मृति संदर्भ में उनका उपयोग करने में सक्षम होना था, जहां साझा स्मृति की मात्रा से कम हो सकती है, एसबीओ सीमा विभिन्न कार्यान्वयन का उपयोग कर सकती है।

उदाहरण के लिए मैं एक स्थिति है जहाँ मैं एसटीडी के दो उदाहरणों :: प्रक्रिया प्रति स्ट्रिंग एक एक आम ब्लॉक स्मृति के जो शायद SBO करने की तुलना में छोटे या बराबर ऊपरी सीमा साझा करने हो सकता है करना चाहते हैं।

संभवतः संबंधित: May std::vector make use of small buffer optimization?

typedef std::vector<int,mysharedmemallocator> shmvtype; 

shmvtype v(2,0); //<-- if SBO then error as memory is allocated on 
       //stack not via the allocator 

v[1] = 1234; //<-- if SBO then error as wrong piece of memory 
       // is being modified. 

एक और उदाहरण है कि साझा स्मृति पर आधारित नहीं है के रूप में इस पर कुछ लोगों के लिए चीजों को मुश्किल लगता है पर देखने की सुविधा देता है। कहते हैं कि मैं एक संभाजक कि मूल्य के साथ स्मृति यह आवंटित भरता के साथ मेरी std :: basic_string या std :: वेक्टर आदि विशेषज्ञ करना चाहते हैं 0xAB व्हिस्मी के अलावा अन्य किसी कारण के लिए बुला इकाई को वापस सूचक पेश करने से पहले।

एक कंटेनर है कि इस नए संभाजक के साथ विशेष है, लेकिन यह भी SBO का उपयोग करता है, अपने SBO आधारित 0xAB पैटर्न से भर स्मृति नहीं होगा। उदाहरण के लिए:

typedef std::basic_string<char,myfillmemallocator> stype 

stype s; 
s.resize(2); 

assert(s[0] == 0xAB); // if SBO this will fail. 

उत्तर

4

कस्टम allocators को लागू करने के इरादे से एक उन्हें एक साझा स्मृति संदर्भ में उपयोग करने

यह हो सकता है कि आप इसे साथ क्या करना चाहते हैं क्या, सक्षम होने के लिए था, लेकिन यही कारण है कि वे मौजूद हैं। दरअसल, सी ++ 98/03 में basic_string के अपवाद के साथ, यह वस्तुओं के बीच शेयर आबंटित स्मृति करने के लिए कानूनी सब पर है। वे आवंटक वस्तुओं को साझा कर सकते हैं, ताकि वे अपनी याददाश्त एक ही स्थान से प्राप्त कर सकें। लेकिन एक वस्तु के संशोधनों के लिए गैरकानूनी किसी अन्य पर प्रभाव डालना अवैध है; प्रत्येक उदाहरण अलग होना चाहिए।

कॉपी-ऑन-राइट तार ही काम करते हैं, क्योंकि इस प्रणाली मानता है कि एक चरित्र के लिए किसी भी गैर स्थिरांक का उपयोग यह करने के लिए लिखेंगे, इस प्रकार एक प्रति प्रदर्शन। और सी ++ 11 में, basic_string इस तरह की कॉपी-ऑन-राइट-स्टाइल सामग्री करने से मना कर दिया गया है।

उदाहरण के लिए मैं एक स्थिति है जहाँ मैं एसटीडी के दो उदाहरणों :: प्रक्रिया प्रति स्ट्रिंग एक स्मृति का एक आम ब्लॉक साझा करने में हो सकता है करना चाहते हैं जो शायद SBO ऊपरी सीमा के तुलना में छोटे या बराबर।

आपकी खुद की कक्षा लिखने के बिना यह संभव नहीं है। आवंटक केवल उस नियंत्रण को नियंत्रित करता है जहां स्मृति आती है। क्या आप चाहते रहे हैं गारंटी कॉपी-ऑन-राइट स्ट्रिंग या साझा स्ट्रिंग वर्ग के कुछ प्रकार है।

क्या आप चाहते हैं एक कंटेनर वर्ग विशेष रूप से इस प्रयोजन के लिए डिजाइन की आवश्यकता है।

+1

निकोल टिप्पणी के लिए धन्यवाद, लेकिन केवल एक सवाल है, क्या कोई भी आवंटक नहीं है जो साझा स्मृति आवंटित करता है, और ऑफ़सेट पॉइंटर अवधारणा के माध्यम से स्मृति को उपनाम करता है - इस तरह यह सामान्य रूप से (boost.interprocess) किया जाता है, नहीं यकीन है कि मैं समझता हूं कि ऐसा क्यों नहीं किया जा सकता है। –

+2

@Seminar: और क्या होता है अगर आपको लगता है कि स्ट्रिंग नकल? क्या होता है यदि आप उस स्ट्रिंग में कोई वर्ण डालते हैं, तो संभावित रूप से पुनर्वितरण का कारण बनता है? यह स्पष्ट है नहीं क्या इन आपरेशनों में से किसी का अर्थ विज्ञान होना चाहिए, लेकिन एक बात स्पष्ट है: जो कुछ भी अर्थ विज्ञान रहे हैं, वे अर्थ विज्ञान कार्यान्वयन खुद की जरूरत के बारे में पता कर रहे हैं। यही है, आपको एक विशिष्ट कंटेनर कार्यान्वयन की आवश्यकता है जो चीजों को एक निश्चित तरीके से करता है। –

+1

साझा स्ट्रिंग से दूसरी स्ट्रिंग में प्रतिलिपि के संबंध में एक आम प्रतिलिपि है, लक्ष्य स्ट्रिंग को साझा स्मृति की उम्मीद नहीं की जाएगी, यह भी वही तरीका है, सामान्य std :: स्ट्रिंग से कॉपी साझा स्ट्रिंग डेटा की प्रतिलिपि बनाई जाती है विशेष संभाजक द्वारा प्रदान की साझा स्मृति में - तो इस सवाल का –