दिलचस्प पोस्ट
कैसे एक आम पूर्वज के बिना दो शाखाओं को मर्ज करने के लिए? एक ORM या सादे एसक्यूएल का उपयोग करना? Google स्थल API – REQUEST_DENIED Google मानचित्र परिणामों पर "खोज क्षेत्र" रूपरेखा जोड़ें पायथन की "इस यूनिकोड के लिए सबसे अच्छा ASCII" डेटाबेस कहां है? स्क्रीन कैप्चरिंग का सबसे तेज तरीका कोर डेटा पृष्ठभूमि संदर्भ सबसे अच्छा अभ्यास दो इनलाइन ब्लॉक तत्व, प्रत्येक 50% चौड़े, एक पंक्ति में एक तरफ फिट नहीं होते हैं एक बैश स्क्रिप्ट का उपयोग करके डुप्लिकेट प्रविष्टियों को निकालें तरीके के साथ एक jQuery प्लगइन बनाने के लिए कैसे? XPath परीक्षण अगर नोड मान संख्या है mysqli: क्या यह एक कथन में कई क्वेरी तैयार कर सकता है? क्या कोई पायथन में __all__ समझा सकता है? जैकील / तरल Templating: साल के लिए ब्लॉग पोस्ट करने के लिए कैसे? संदर्भ जावास्क्रिप्ट बिना वस्तु क्लोन करें

कस्टम सी ++ आवर्तकों के सम्मोहक उदाहरण?

एक कस्टम समाधान के पक्ष में std::allocator खाई के लिए कुछ बहुत अच्छा कारण क्या हैं? क्या आप किसी भी परिस्थितियों में चलाते हैं जहां यह सही, प्रदर्शन, स्केलेबिलिटी इत्यादि के लिए बिल्कुल आवश्यक था? कोई भी वास्तव में चालाक उदाहरण?

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

वेब के समाधान से एकत्रित समाधान "कस्टम सी ++ आवर्तकों के सम्मोहक उदाहरण?"

जैसा कि मैंने यहां उल्लेख किया है , मैंने देखा है कि इंटेल टीबीबी के कस्टम एसटीएल आबंटक एक मल्टीथ्रेडेड ऐप के प्रदर्शन को एक सिंगल

 std::vector<T> 

सेवा मेरे

 std::vector<T,tbb::scalable_allocator<T> > 

(यह टीबीबी के निफ्टी धागे-निजी हेपों का उपयोग करने के लिए आवंटक को स्विच करने का एक त्वरित और सुविधाजनक तरीका है; इस दस्तावेज़ में पृष्ठ 7 देखें)

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

ईएएसटीएल – इलेक्ट्रॉनिक आर्ट्स स्टैंडर्ड टेम्प्लेट लाइब्रेरी

मैं एक एमएमएपी-ऑलोकेटर पर काम कर रहा हूं जो वैक्टर को स्मृति-मैप किए गए फ़ाइल से मेमोरी का उपयोग करने की अनुमति देता है। लक्ष्य वेक्टर है जो भंडारण का उपयोग करते हैं जो सीधे वर्चुअल मेमोरी में मैमेट द्वारा मैप किए जाते हैं। हमारी समस्या किसी भी प्रतिलिपि ओवरहेड के साथ स्मृति में वास्तव में बड़ी फ़ाइलों (> 10 जीबी) को पढ़ने में सुधार करना है, इसलिए मुझे इस कस्टम आवंटन की आवश्यकता है

अब तक मेरे पास कस्टम ऑलोकेटर (जो कि स्टडी :: आबंटक से प्राप्त होता है) का कंकाल है, मुझे लगता है कि यह स्वयं आवंटन लिखने के लिए एक अच्छा प्रारंभिक बिंदु है। आप चाहते हैं कि किसी भी तरह से कोड के इस टुकड़े का उपयोग करने के लिए स्वतंत्र महसूस करें:

 #include <memory> #include <stdio.h> namespace mmap_allocator_namespace { template <typename T> class mmap_allocator: public std::allocator<T> { public: typedef size_t size_type; typedef T* pointer; typedef const T* const_pointer; template<typename _Tp1> struct rebind { typedef mmap_allocator<_Tp1> other; }; pointer allocate(size_type n, const void *hint=0) { fprintf(stderr, "Alloc %d bytes.\n", n*sizeof(T)); return std::allocator<T>::allocate(n, hint); } void deallocate(pointer p, size_type n) { fprintf(stderr, "Dealloc %d bytes (%p).\n", n*sizeof(T), p); return std::allocator<T>::deallocate(p, n); } mmap_allocator() throw(): std::allocator<T>() { fprintf(stderr, "Hello allocator!\n"); } mmap_allocator(const mmap_allocator &a) throw(): std::allocator<T>(a) { } template <class U> mmap_allocator(const mmap_allocator<U> &a) throw(): std::allocator<T>(a) { } ~mmap_allocator() throw() { } }; } 

इसका प्रयोग करने के लिए, एक एसटीएल कंटेनर को निम्नानुसार घोषित करें:

 using namespace std; using namespace mmap_allocator_namespace; vector<int, mmap_allocator<int> > int_vec(1024, 0, mmap_allocator<int>()); 

यह उदाहरण के लिए उपयोग किया जा सकता है जब भी मेमोरी को आवंटित किया जाता है। क्या आवश्यक है कि रिबंड स्ट्रेट है, अन्यथा वेक्टर कंटेनर सुपर-क्लासेस आवंटित / डीअलॉन्क तरीके का उपयोग करता है।

अद्यतन: स्मृति मानचित्रण आवंटन अब https://github.com/johannesthoma/mmap_allocator पर उपलब्ध है और एलजीपीएल है। अपनी परियोजनाओं के लिए इसका उपयोग करने के लिए स्वतंत्र महसूस करें

मैं एक MySQL स्टोरेज इंजन के साथ काम कर रहा हूं जो अपने कोड के लिए c ++ का उपयोग करता है। स्मृति के लिए MySQL के साथ प्रतिस्पर्धा करने के बजाय हम MySQL मेमोरी सिस्टम का उपयोग करने के लिए एक कस्टम ऑलोकेटर का उपयोग कर रहे हैं। यह हमें यह सुनिश्चित करने के लिए अनुमति देता है कि हम मेमोरी का उपयोग कर रहे हैं क्योंकि उपयोगकर्ता का उपयोग करने के लिए MySQL कॉन्फ़िगर किया गया है, और "अतिरिक्त" नहीं।

ढेर के बजाय स्मृति पूल का उपयोग करने के लिए कस्टम आवर्तक का उपयोग करने के लिए यह उपयोगी हो सकता है। यह कई अन्य लोगों के बीच एक उदाहरण है

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

मैंने कस्टम एसटीएल आबंटक के साथ सी ++ कोड नहीं लिखा है, लेकिन मैं सी + + में लिखे गए एक वेबसर्वर की कल्पना कर सकता हूं जो एक HTTP अनुरोध का जवाब देने के लिए आवश्यक अस्थायी डेटा को स्वचालित हटाने के लिए एक कस्टम आवंटक का उपयोग करता है। कस्टम आवंटक प्रतिक्रिया उत्पन्न होने के बाद एक बार सभी अस्थायी डेटा को मुक्त कर सकते हैं।

एक कस्टम आवंटन (जो मैंने उपयोग किया है) के लिए एक अन्य संभावित उपयोग का मामला एक इकाई परीक्षण लिख रहा है यह साबित करने के लिए कि फ़ंक्शन का व्यवहार उसके इनपुट के कुछ हिस्से पर निर्भर नहीं करता है कस्टम आवंटन किसी भी पैटर्न के साथ मेमोरी क्षेत्र को भर सकता है

मैं कस्टम आवर्तक का उपयोग कर रहा हूं; आप कह सकते हैं कि यह अन्य कस्टम डायनामिक मेमोरी प्रबंधन के आसपास काम करना था।

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

समस्या यह है, हम एक एम्बेडेड वातावरण में चल रहे हैं – एक विस्तारित अवधि के दौरान वास्तव में रिसाव का पता लगाने के लिए पर्याप्त मेमोरी नहीं है। कम से कम, मानक रैम में नहीं – कस्टम आवंटन कार्यों के माध्यम से कहीं और उपलब्ध रैम का एक और ढेर है।

समाधान: कस्टम ऑलोकेटर लिखो जो विस्तारित ढेर का उपयोग करता है, और इसे केवल मेमोरी लीक ट्रैकिंग आर्किटेक्चर के आंतरिकों में ही प्रयोग किया जाता है … अन्य सभी नई सामान्य / डिलीट ओवरलोड्स जो लीक ट्रैकिंग यह ट्रैकर पर नज़र रखने से बचा जाता है (और कुछ अतिरिक्त पैकिंग कार्यक्षमता भी प्रदान करता है, हम ट्रैकर नोड्स के आकार को जानते हैं)

हम इसका उपयोग उसी तरह के लिए फ़ंक्शन लागत प्रोफाइलिंग डेटा को भी रखने के लिए करते हैं; प्रत्येक फ़ंक्शन कॉल और रिटर्न के लिए प्रविष्टि लिखना, साथ ही थ्रेड स्विच भी तेजी से महंगा हो सकता है। कस्टम आवंटक फिर से हमें एक बड़े डीबग मेमोरी क्षेत्र में छोटा एलोकॉन्स देता है।

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

GPUs या अन्य सह-प्रोसेसर के साथ काम करते समय यह विशेष रूप से मुख्य स्मृति में डेटा संरचना आवंटित करने के लिए कभी-कभी उपयोगी होता है। मेमोरी आवंटित करने का यह विशेष तरीका एक सुविधाजनक फ़ैशन में कस्टम ऑलोकेटर में लागू किया जा सकता है।

एक्सेलेरेटर रनटाइम के माध्यम से कस्टम आवंटन का कारण फायदेमंद हो सकता है जब एक्सेलेरेटर्स का उपयोग निम्न होता है:

  1. कस्टम आवंटन के माध्यम से त्वरक रनटाइम या ड्राइवर को स्मृति ब्लॉक के बारे में सूचित किया जाता है
  2. इसके अलावा ऑपरेटिंग सिस्टम यह सुनिश्चित कर सकता है कि स्मृति के आवंटित ब्लॉक पृष्ठ-लॉक (कुछ कॉल इस पिन किए गए मेमोरी ) हैं, अर्थात, ऑपरेटिंग सिस्टम का वर्चुअल स्मृति सबसिस्टम पेज के अंदर या मेमोरी को स्थानांतरित नहीं कर सकता है या नहीं
  3. अगर 1. और 2. एक पृष्ठ-लॉक मेमोरी ब्लॉक के बीच एक डाटा ट्रांसफर और एक एक्सेलेरेटर का अनुरोध किया जाता है, तो रनटाइम सीधे मुख्य मेमोरी में डेटा एक्सेस कर सकता है क्योंकि यह जानता है कि यह कहां है और यह सुनिश्चित किया जा सकता है कि ऑपरेटिंग सिस्टम नहीं था इसे ले जाएं / निकालें
  4. यह एक स्मृति प्रतिलिपि सहेजता है जो एक गैर-पृष्ठ-लॉक तरीके से आवंटित स्मृति के साथ घटित होती है: डेटा को मुख्य स्मृति में एक पेज-लॉक स्टेजिंग क्षेत्र में त्वरण के साथ कॉपी किया जाना चाहिए, डेटा ट्रांसफर (डीएमए के माध्यम से) )

एक जरूरी परिस्थिति: जब लेखन कोड जो कि मॉड्यूल (एक्सई / डीएलएल) सीमाओं के बीच काम करना चाहिए, तो अपने आवंटन और विलोपन को केवल एक मॉड्यूल में चलाना आवश्यक है।

जहां मैं इस पर चला गया Windows पर एक प्लगइन वास्तुकला था यह जरूरी है कि, उदाहरण के लिए, यदि आप DLL सीमा में std :: string पास करते हैं, तो स्ट्रिंग के किसी भी पुनर्व्यवस्था में ढेर से उत्पन्न होता है, जहां से यह उत्पन्न हुआ है, जो डीएलएल में ढेर नहीं है जो अलग हो सकता है *।

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

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

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

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

अन्य कई बार मैं एम्बेडेड सिस्टम के संदर्भ में अपने स्वयं के कस्टम आवंटन को लिख सकता हूं, उदाहरण के लिए यदि अनुक्रम के लिए मेमोरी मुख्य राम में नहीं है, जैसा कि इन प्लेटफार्मों पर अक्सर मामला हो सकता है

साझा मेमोरी के लिए यह महत्वपूर्ण है कि न केवल कंटेनर का सिर, बल्कि इसमें डेटा को साझा स्मृति में संग्रहित किया जाता है

बूस्टर का आवंटन :: इंटरप्रोसेज एक अच्छा उदाहरण है। हालांकि, जैसा कि आप यहां पढ़ सकते हैं यह सब पर्याप्त नहीं है, बनाने के लिए सभी एसटीएल कंटेनर मेमोरी संगत साझा करने के लिए (विभिन्न प्रक्रियाओं में अलग-अलग मैपिंग ऑफसेट के कारण, पॉइंटर्स "ब्रेक" हो सकते हैं)।

आलोकिकों पर आंद्रेई अलेक्जेंडरस्कू के सीपीसीन 2015 के बारे में बात करने के लिए अनिवार्य लिंक:

https://www.youtube.com/watch?v=LIb3L4vKZ7U

अच्छी बात यह है कि सिर्फ उन्हें तैयार करने से आपको उन विचारों के बारे में सोचना पड़ता है जिनसे आप उनका प्रयोग करेंगे 🙂

मैं व्यक्तिगत रूप से लोकी :: ऑलोकेटर / स्मॉल ऑब्जेक्ट का इस्तेमाल छोटी वस्तुओं के लिए मेमोरी उपयोग को अनुकूलित करने के लिए करता हूं – यदि आपको वास्तव में छोटी वस्तुएं (1 से 256 बाइट्स) की सामान्य मात्रा में काम करना है तो यह अच्छी दक्षता और संतोषजनक प्रदर्शन दिखाता है। अगर हम कई अलग-अलग आकार की छोटी वस्तुओं की मध्यम मात्रा आवंटित करने के बारे में बात करते हैं तो यह मानक सी ++ से नया / डिलीट आवंटन से 30 गुना अधिक कुशल हो सकता है। इसके अलावा, "त्वरित हिएप" नामक एक वीसी-विशिष्ट समाधान है, यह सर्वोत्तम संभव प्रदर्शन लाता है (आवंटन और निस्तारण कार्य केवल ब्लॉक में दिए गए ब्लॉक के पते को पढ़ने / लिखने के लिए, क्रमशः 99 तक करता है। (9)% मामलों – सेटिंग्स और आरंभीकरण पर निर्भर करता है), लेकिन एक उल्लेखनीय ओवरहेड की लागत पर – प्रत्येक हद तक दो पॉइंटर्स की आवश्यकता होती है और प्रत्येक नए मेमोरी ब्लॉक के लिए एक अतिरिक्त। वस्तुओं के विशाल (10 000 ++) राशियों के साथ काम करने के लिए यह सबसे तेज़ संभव समाधान है, यदि आपको ऑब्जेक्ट आकार की एक बड़ी विविधता की आवश्यकता नहीं है, तो वस्तुओं की मात्रा तैयार की जाती है और हटाई जाती है (यह प्रत्येक ऑब्जेक्ट आकार के लिए एक व्यक्तिगत पूल बनाता है, 1 से 1023 बाइट्स वर्तमान कार्यान्वयन में, इसलिए प्रारंभिक लागत समग्र प्रदर्शन को बढ़ावा दे सकती है, लेकिन कोई भी इसके आगे-आगे जाकर कुछ डमी ऑब्जेक्ट को आवंटित कर सकता है, इससे पहले कि यह एप्लिकेशन का प्रदर्शन-महत्वपूर्ण चरण (ओं) में प्रवेश करे)।

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

एक ग्राफिक सिमुलेशन में, मैंने कस्टम ऑलोकेटर्स के लिए उपयोग किया है I

  1. संरेखण की बाधाएं std::allocator सीधे समर्थन नहीं किया था
  2. अल्पावधि के लिए अलग पूल (सिर्फ इस फ्रेम) और लंबे समय तक रहने वाले आवंटन का उपयोग करके विखंडन को न्यूनतम करना।

कुछ समय पहले मुझे यह समाधान मेरे लिए बहुत उपयोगी पाया: एसटीएल कंटेनरों के लिए फास्ट सी +11 11 आबंटक यह वीएस 2017 (~ 5x) पर और जीसीसी (~ 7x) पर एसटीएल कंटेनरों की गति बढ़ाता है। यह मेमोरी पूल पर आधारित एक विशेष उद्देश्य आबंटक है। इसका इस्तेमाल केवल एसटीएल कंटेनर के साथ किया जा सकता है, जो कि आपके लिए पूछ रहे तंत्र के लिए है।