2012-05-21 15 views
6

मेरे पास बहु-थ्रेडेड सेक्शन है जहां थ्रेड को डेटा के कई बड़े सेगमेंट आवंटित करने की आवश्यकता होती है, प्रत्येक को ~ 100 एमबी कहते हैं, बफर के रूप में उपयोग करने के लिए। इसके अलावा, बफर को रन टाइम पर कई बार आकार देने की आवश्यकता हो सकती है।मेमोरी आवंटन सुझाव

प्राकृतिक समाधान realloc का उपयोग करना है, लेकिन यह स्मृति को स्थानांतरित कर सकता है जिसकी आवश्यकता नहीं है। free/malloc बफर का आकार बदलने के लिए जोड़ी मुझे डर है कि हाथ से अन्य समस्याएं पैदा होने से पहले विखंडन और स्मृति को सुरक्षित कर सकता है।

स्मृति का आवंटन/पुन: आवंटित करने के लिए मैं इसके बजाय क्या उपयोग कर सकता हूं?

+0

"हाथ से पहले स्मृति को सुरक्षित करना अन्य समस्याएं पैदा करता है" तो पूलिंग आवंटन उपयुक्त नहीं है? और क्या आप मानक-आश रहना चाहते हैं, या आप एक कस्टम आवंटन योजना के लिए दृष्टिकोण की तलाश में हैं? – Corbin

+0

@ कॉरबिन मुझे नहीं लगता कि मेरे मामले में पूल अच्छे हैं - लिनक्स में NUMA domanis में पहली बार स्पर्श नीति है। मैं * पोर्टेबल * समाधान – Anycorn

+0

बफर में डेटा के प्रबंधन के किसी भी तरीके से रहना चाहता हूं जैसे कि आप आकार बदलने की आवश्यकता से बच सकते हैं? या यहां तक ​​कि बफर आकार पर ऊपरी बाउंड डाल दिया? हार्डवेयर पर आपके पास कितनी मेमोरी है? –

उत्तर

5

free और malloc का उपयोग करें। इससे विखंडन की समस्या नहीं होगी।

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

इसके अलावा, बफर के आकार के कारण, अधिकांश आवंटक प्रत्येक बफर के लिए कर्नेल से समर्पित क्षेत्र का अनुरोध करेंगे। लिनक्स/ओएस एक्स/बीएसडी पर, इसका अर्थ प्रत्येक बफर के दृश्यों के पीछे एक अज्ञात mmap है। यह पता स्थान के विखंडन का कारण बन सकता है, लेकिन वर्चुअल एड्रेस स्पेस मूल रूप से 64-बिट सिस्टम पर निःशुल्क है, और कुछ सौ मेग 32-बिट पर कोई समस्या नहीं है।

तो free और malloc का उपयोग करें।

वैकल्पिक: आपको प्रत्येक बफर को आपकी आवश्यकता से बड़ा बनाने के लिए तेज़ी से मिल सकती है। जिस तरह से malloc आधुनिक यूनिक्स पर काम करता है, कोई भी पृष्ठ जिसे आप लिखने के लिए नहीं लिखते हैं, स्मृति का उपभोग नहीं करते हैं।

तो यदि आप malloc एक 500 एमबी बफर का उपयोग करते हैं, लेकिन केवल पहले 100 एमबी का उपयोग करते हैं, तो आपका प्रोग्राम वास्तव में malloc एक 100 एमबी बफर से अधिक स्मृति का उपयोग नहीं करता है और पूरी चीज का उपयोग करता है। आपको इस तरह से अधिक पता स्थान विखंडन मिलता है, लेकिन 64-बिट सिस्टम पर कोई समस्या नहीं है, और आप हमेशा आवंटन आकार को ट्यून कर सकते हैं ताकि यह 32-बिट सिस्टम पर भी काम कर सके।

के रूप में सुझाव mmap का उपयोग करने के लिए, mmap/munmap के लिए अधिक सरल अंतरफलक के रूप में malloc/free का सिर्फ लगता है, जो है क्या यह बड़े आवंटन के लिए है (1 MiB एक आम सीमा है)।

+0

क्या कोई संदर्भ है जो वर्णन करता है कि किस स्थिति में विखंडन होता है? – Anycorn

+0

कुछ अजीब चीजें हैं जो आप कर सकते हैं, जैसे कि 16-बाइट हिस्सों का एक गुच्छा आवंटित करना, अजीब संख्या वाले लोगों को मुक्त करना, फिर 24-बाइट हिस्सों का एक गुच्छा आवंटित करना, अजीब संख्या वाले लोगों को मुक्त करना, और चीजों को करना जारी रखना उस। यह मूल रूप से 'malloc' के लिए सबसे खराब स्थिति परिदृश्य है, लेकिन कुल स्मृति बर्बाद होने के प्रतिशत पर बाध्य है। –

+1

@ एनीकॉर्न: असल में, चूंकि हम ऐसे बड़े बफर के बारे में बात कर रहे हैं, यह वास्तव में * पता स्थान * विखंडन और स्मृति स्मृति विखंडन नहीं है। यदि आप 64-बिट पर हैं, तो पता स्थान विखंडन ऐसी चीज नहीं है जिसकी आप परवाह है। –

1

malloc/realloc/free के साथ अपने समाधान को कार्यान्वित करें और इसे प्रोफाइल करें। यदि स्मृति आवंटन एक समस्या है, तो आप फेसबुक के jemalloc, या Google के tcmalloc जैसे मॉलोक के बेहतर कार्यान्वयन का उपयोग कर सकते हैं।

दोनों की तुलना के लिए C++ memory allocation mechanism performance comparison (tcmalloc vs. jemalloc) देखें।

वे दोनों आंतरिक/बाहरी विखंडन को संभालने में बहुत अच्छे हैं।

+1

100 एमबी बफर के लिए, आपको जेमलोक या टीसीएमएलओसी के बीच कोई अंतर नहीं दिखाई देगा क्योंकि वे दोनों एक निश्चित थ्रेसहोल्ड (1 एमआईबी सामान्य) पर आवंटन के लिए सीधे कर्नेल से पृष्ठों का अनुरोध करते हैं। आपके सिस्टम पर डिफ़ॉल्ट 'malloc' वही काम करेगा। –

+0

@DietrichEpp डिफ़ॉल्ट मैलोक के साथ समस्या बहु-थ्रेडेड अनुप्रयोगों के मामले में लॉक-विवाद है। हालांकि, मैं निश्चित रूप से उनका उपयोग करने से पहले अपने कार्यक्रम को प्रोफाइल करूँगा। –

+1

यदि आप 100 एमबी बफर के बारे में बात कर रहे हैं, तो यहां तक ​​कि एक अत्यधिक प्रतिस्पर्धी लॉक की लागत न्यूनतम होने वाली है, क्योंकि आपको वैसे भी एक सिस्कल बनाना है। वास्तव में –

4

बस realloc का उपयोग करें। एक आधुनिक प्रणाली पर, भले ही बफर को नए पते पर ले जाया जाता है, फिर भी पृष्ठ तालिका तालिकाओं (लिनक्स, mremap पर) में हेरफेर करके कदम होगा; मुझे यकीन है कि अन्य प्रणालियों में एक समान तंत्र है) और डेटा कॉपी करके नहीं। (यहां ध्यान दें कि मैं बड़े बफर मान रहा हूं; छोटे बफर के लिए, आमतौर पर कुछ सौ केबी से कम, वास्तविक प्रतिलिपि होगी।)

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

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