2011-02-03 16 views
5

मेरी परियोजनाओं में से एक में, मैंने एक बड़ी बाधा के रूप में std::deque<T>::clear() पर एक कॉल की पहचान की।समर्पित धागे में एसटीएल साफ़ करना

इसलिए मैं एक समर्पित, कम प्राथमिकता सूत्र में इस कार्रवाई को ले जाने का फैसला किया:

template <class T> 
void SomeClass::parallelClear(T& c) 
{ 
    if (!c.empty()) 
    { 
     T* temp = new T; 
     c.swap(*temp); // swap contents (fast) 

     // deallocate on separate thread 
     boost::thread deleteThread([=]() { delete temp; }); 

     // Windows specific: lower priority class 
     SetPriorityClass(deleteThread.native_handle(), BELOW_NORMAL_PRIORITY_CLASS); 
    } 
} 

void SomeClass:clear(std::deque<ComplexObject>& hugeDeque) 
{ 
    parallelClear(hugeDeque); 
} 

यह (VisualC++ 2010) ठीक से काम करने लगता है, लेकिन मुझे आश्चर्य है कि अगर मैं किसी भी प्रमुख दोष अनदेखी की। मैं उपरोक्त कोड के बारे में आपकी टिप्पणियों का स्वागत करता हूं।

अतिरिक्त जानकारी:

SomeClass:clear() एक जीयूआई-धागे से कहा जाता है, और यूजर इंटरफेस कॉल रिटर्न जब तक उत्तर नहीं देता है। दूसरी तरफ, hugeQueue, समाशोधन के बाद कई सेकंड के लिए उस धागे द्वारा उपयोग की जाने वाली संभावना नहीं है।

+0

क्या यह धीमा है भले ही आप डीबगर संलग्न किए बिना चलाए? –

+0

एसटीएल कंटेनर स्वयं थ्रेड सुरक्षित नहीं हैं, इसलिए आपके कोड को एक बहु थ्रेडेड वातावरण में कंटेनर पर संचालन करने से पहले इसे आधार के रूप में लेना चाहिए। – DumbCoder

+0

हां। वास्तव में उपयोग किए जाने वाले डेक में लाखों ऑब्जेक्ट्स (इनट्स नहीं) –

उत्तर

2

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

मैं व्यक्तिगत रूप से आवंटन/डीलोकेशन पैटर्न से मेल खाने के लिए कस्टम आवंटन का उपयोग करने का सुझाव देता हूं, यहां सबसे अच्छा प्रदर्शन सुधार होगा- याद रखें कि धागे बनाने में एक गैर-तुच्छ ओवरहेड होता है।

संपादित करें: यदि आप जीयूआई/वर्कर थ्रेड शैली थ्रेडिंग डिज़ाइन का उपयोग कर रहे हैं, तो वास्तव में, आपको और प्रबंधित करना चाहिए कार्यकर्ता धागे पर डेक को नष्ट करना।

+0

@DeadMG: कोई प्रति-प्रणाली के आधार पर क्रमबद्धता को बंद कर सकता है? या यह एक संकलन समय सेटिंग है? –

+0

तो इस कस्टम आवंटक में, आप एक समर्पित ढेर का उपयोग करेंगे, जिसे आप साफ़ करने पर एक बार में सभी को हटा दें? –

+0

@Daniel: जहां तक ​​मुझे पता है, आप रनटाइम पर सेटिंग्स बदल सकते हैं। आपके कस्टम आवंटक के लिए, मुझे आपके आवंटन पैटर्न के बारे में पर्याप्त जानकारी नहीं है- लेकिन यदि आपके पास एक बहुत बड़ी वस्तु और विध्वंस की श्रृंखला है, तो यह पूरी ढेर को हटाने के लिए उचित हो सकता है। बेशक, आपको अभी भी शामिल वस्तुओं को नष्ट करना है। – Puppy

1

ध्यान रखें, यह सुनिश्चित नहीं है कि इससे आपके आवेदन के समग्र प्रदर्शन में सुधार होगा। विंडोज मानक ढेर (भी कम विखंडन ढेर) आवंटन जानकारी को अक्सर एक धागे से दूसरे में प्रेषित करने के लिए नहीं रखा जाता है। यह काम करेगा, लेकिन यह प्रसंस्करण के काफी ऊपर का उत्पादन कर सकता है।

ढेर स्मृति allocator के दस्तावेजीकरण हो सकता है एक प्रारंभिक बिंदु है कि में गहरी मिलता है: http://www.cs.umass.edu/~emery/hoard/hoard-documentation.html

आपका दृष्टिकोण हालांकि जवाबदेही में सुधार होगा आदि

+0

आपके उत्तर के लिए धन्यवाद। मेरे मामले में, ढेर को आम तौर पर थ्रेड ए से 1'000'000 गुना तक पहुंचाया जाएगा, फिर थ्रेड बी से उसी राशि (ए द्वारा आवंटित वस्तुओं को हटाने के लिए), और इसी तरह। तो मैं अक्सर स्विच नहीं कर रहा हूँ। लेकिन मैं विशिष्ट आवंटकों के साथ विकल्पों की जांच करूंगा (आवेदन का शेष भाग पहले ही लागू होता है और इसका स्वयं का विशिष्ट मेमोरी प्रबंधन दिनचर्या का उपयोग करता है)। –

0

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

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