दिलचस्प पोस्ट
स्प्रिंग बूट स्थिर सामग्री की सेवा नहीं दे रहा है MySQL: किसी कॉलम से केवल अनन्य मान चुनें सी ++ में एक गतिशील सरणी कैसे प्रारंभ करें? रेल 3 में "चालू" वर्ग को एनएवी में जोड़ने का सर्वोत्तम तरीका डेटाबेस ईएवी पेशेवरों / विपक्ष और विकल्प जावा स्विंग में आपको विंडो के लिए Win32 विंडो हैंडल (एचडब्ल्यूडी) संदर्भ कैसे मिलता है? एक DOM में डुप्लिकेट आईडी की जांच करने के लिए JQuery "सर्वर के लिए संस्करण" को बनाए रखने का सही तरीका क्या है – गिट में केवल कॉन्फ़िग फाइल बदल दी गई है? एंड्रॉइड 6.0 में डोज मोड में अलार्म मैनेजर कैसे काम करता है? पृष्ठ ताज़ा / नेविगेशन पर ट्विटर बूटस्ट्रैप संकुचित करें जावास्क्रिप्ट / jQuery के साथ एक HTML तत्व से सभी गुण प्राप्त करें एंड्रॉइड आईसीएस पर सिस्टम बार को छुपाने का आसान तरीका जावास्क्रिप्ट में क्या अच्छा टेम्पलेट भाषा समर्थित है? अजगर पांडा के साथ काम करने के लिए नोटबुक में बड़ी सीएसवी फाइल अपलोड करने का सबसे तेज़ तरीका क्या है? Async नेटवर्क ऑपरेशन कभी समाप्त नहीं

लूप के लिए सी + + ओपनएमपी समानांतर – स्टडी :: वेक्टर के विकल्प

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

Solutions Collecting From Web of "लूप के लिए सी + + ओपनएमपी समानांतर – स्टडी :: वेक्टर के विकल्प"

जो प्रश्न आप लिंक करते हैं, वह इस तथ्य के बारे में बात कर रहा था कि "एसटीएल वेक्टर कंटेनर स्थिति में थ्रेड-सुरक्षित नहीं है जहां कई थ्रेड एकल कंटेनर में लिखते हैं"। यह केवल सच है, जैसा कि सही तरीके से बताया गया है, यदि आप विधियों को कॉल करते हैं जो कि अंतर्निहित सरणी के पुनर्व्यासन का कारण बन सकता है जो std::vector रखता है push_back() , pop_back() और insert() इन खतरनाक विधियों के उदाहरण हैं।

यदि आपको थ्रेड सुरक्षित रीअलोकेशन की आवश्यकता है, तो पुस्तकालय इंटेल थ्रेड बिल्डिंग ब्लॉक आपको समवर्ती वेक्टर कंटेनर प्रदान करता है। आपको एकल थ्रेड प्रोग्राम में tbb :: concurrent_vector का उपयोग नहीं करना चाहिए क्योंकि समय यादृच्छिक तत्वों तक पहुंचने में लगने वाला समय std :: vector के समान होता है (जो कि ओ (1) है)। हालांकि, समवर्ती वेक्टर कॉल pop_back() push_back() , pop_back() , एक थ्रेड में सुरक्षित तरीके से insert() , भले ही फिर से आवंटन होता है।

1 संपादित करें: निम्न इंटेल प्रस्तुति के स्लाइड्स 46 और 47 में टीबीबी :: समवर्ती_वेक्टर का उपयोग करते हुए समवर्ती पुन: स्थान का एक उदाहरण देता है

2 संपादित करें: वैसे, यदि आप इंटेल टेड बिल्डिंग ब्लॉक (यह ओपन सोर्स है, तो यह सबसे अधिक कंपलर के साथ काम करता है और इसे OpenMP से सी ++ / सी ++ 11 विशेषताओं के साथ एकीकृत किया जाता है) का उपयोग करना शुरू कर देता है, तो आपको इसकी आवश्यकता नहीं है एक समानांतर_ बनाने के लिए openmp का उपयोग करने के लिए, यहां tbb के उपयोग के लिए parallel_for का एक अच्छा उदाहरण है

मुझे लगता है कि आप ज्यादातर समय OpenMP के साथ std::vector उपयोग कर सकते हैं और अभी भी अच्छा प्रदर्शन किया है। उदाहरण के लिए निम्न कोड समानांतर में std::vectors भरता है और फिर उन्हें अंत में जोड़ती है जब तक आपका मुख्य लूप / फ़ॉल फ़ंक्शन बाधा है, यह सामान्य रूप से अच्छी तरह से काम करना चाहिए और थ्रेड सुरक्षित हो।

 std::vector<int> vec; #pragma omp parallel { std::vector<int> vec_private; #pragma omp for nowait //fill vec_private in parallel for(int i=0; i<100; i++) { vec_private.push_back(i); } #pragma omp critical vec.insert(vec.end(), vec_private.begin(), vec_private.end()); } 

संपादित करें:

OpenMP 4.0 #pragma omp declare reduction का उपयोग कर उपयोगकर्ता द्वारा परिभाषित कटौती की अनुमति देता है। ऊपर दिए गए कोड के साथ सरलीकृत किया जा सकता है

 #pragma omp declare reduction (merge : std::vector<int> : omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end())) std::vector<int> vec; #pragma omp parallel for reduction(merge: vec) for(int i=0; i<100; i++) vec.push_back(i); 

संपादित करें: जो मैंने दिखाया है अब तक सदिश को क्रम में नहीं भरता है यदि आदेश के मामले में ऐसा किया जा सकता है

 std::vector<int> vec; #pragma omp parallel { std::vector<int> vec_private; #pragma omp for nowait schedule(static) for(int i=0; i<N; i++) { vec_private.push_back(i); } #pragma omp for schedule(static) ordered for(int i=0; i<omp_get_num_threads(); i++) { #pragma omp ordered vec.insert(vec.end(), vec_private.begin(), vec_private.end()); } } 

यह प्रत्येक धागा के लिए std :: vector को बचाता है और फिर समानांतर क्षेत्र के बाहर धारावाहिक में उन्हें विलीन करता है। मैंने इस "चाल" के बारे में यहां सीखा है मुझे यकीन नहीं है कि उपयोगकर्ता-निर्धारित कटौती के लिए यह कैसे करना है (या यदि यह संभव है) । यह उपयोगकर्ता द्वारा परिभाषित कटौती के साथ ऐसा करना संभव नहीं है

मुझे एहसास हुआ कि महत्वपूर्ण खंड आवश्यक नहीं है, जिसे मैंने इस प्रश्न से समानांतर-संचयी-उपसर्ग-राशि- in-openmp-communicating-values-between-thread का पता लगाया। इस पद्धति को भी आदेश ठीक भी मिल जाता है

 std::vector<int> vec; size_t *prefix; #pragma omp parallel { int ithread = omp_get_thread_num(); int nthreads = omp_get_num_threads(); #pragma omp single { prefix = new size_t[nthreads+1]; prefix[0] = 0; } std::vector<int> vec_private; #pragma omp for schedule(static) nowait for(int i=0; i<100; i++) { vec_private.push_back(i); } prefix[ithread+1] = vec_private.size(); #pragma omp barrier #pragma omp single { for(int i=1; i<(nthreads+1); i++) prefix[i] += prefix[i-1]; vec.resize(vec.size() + prefix[nthreads]); } std::copy(vec_private.begin(), vec_private.end(), vec.begin() + prefix[ithread]); } delete[] prefix;