2012-10-08 13 views
10

मैं फॉर लूप में समांतरता ब्रेक की जांच कर रहा हूं।समांतर। फॉर और ब्रेक() गलतफहमी?

मैं इस कोड उम्मीद थी:

Parallel.For(0, 10, (i,state) => 
    { 
       Console.WriteLine(i); if (i == 5) state.Break(); 
    } 

सबसे 6 संख्या (0..6) पर उपज के लिए

this और this पढ़ने के बाद मैं अभी भी एक प्रश्न है। न केवल वह यह नहीं कर रही है, लेकिन अलग-अलग परिणाम लंबाई है:

02351486 
013542 
0135642 

बहुत कष्टप्रद। (जहां नरक यहाँ तोड़() {5 के बाद} है ??)

तो मैं MSDN

को देखा

तोड़ पाश करने के लिए बातचीत करने के लिए है कि मौजूदा यात्रा के बाद कोई अन्य पुनरावृत्तियों होने की जरूरत इस्तेमाल किया जा सकता चलाते हैं। यदि ब्रेक को में 0 से 1000 के समानांतर लूप के 100 वें पुनरावृत्ति से बुलाया जाता है, तो 100 से कम सभी पुनरावृत्तियों को अभी भी रन होना चाहिए, लेकिन 101 से 1000 तक पुनरावृत्तियों आवश्यक नहीं हैं।

quesion # 1:

कौन सा पुनरावृत्तियों? समग्र पुनरावृत्ति काउंटर? या प्रति थ्रेड? मुझे यकीन है कि यह प्रति धागा है। कृपया अनुमोदन करें।

प्रश्न # 2:

चलें हम समानांतर + रेंज विभाजन का उपयोग कर रहे (तत्वों के बीच कोई cpu लागत परिवर्तन के कारण) तो यह धागे के बीच डेटा बिताते हैं मान। तो अगर हम (उन के बीच में है और सही डिवीजनों) 4 कोर है:

core #1 got 0..250 
core #2 got 251..500 
core #3 got 501..750 
core #4 got 751..1000 

तो core #1 में धागा कुछ समय value=100 को पूरा करेगा और टूट जाएगा। यह उसका पुनरावृत्ति संख्या 100 होगा। लेकिन core #4 में धागा अधिक क्वांट मिला और वह अब 900 पर है। वह से परे 100'th पुनरावृत्ति है। उसके पास बंद होने के लिए सूचकांक कम 100 नहीं है !! - तो वह उन्हें सब दिखाएगा।

क्या मैं सही हूँ? यही कारण है कि मुझे अपने उदाहरण में 5 से अधिक तत्व क्यों मिलते हैं?

प्रश्न # 3:

कैसे cn मैं सच में जब (i == 5) तोड़ने?

पेज।

मेरा मतलब है, चलो! जब मैं Break() करता हूं, तो मैं चीजों को लूप को रोकना चाहता हूं। मैं For लूप नियमित रूप से करता हूं।

उत्तर

10

अधिकतर 6 संख्याओं (0..6) पर उपज करने के लिए।

समस्या यह है कि यह अधिकतर 6 संख्या पर उपज नहीं होगी।

क्या होता है, जब आप 5 की अनुक्रमणिका के साथ लूप दबाते हैं, तो आप "ब्रेक" अनुरोध भेजते हैं। Break() लूप को >5 किसी भी मान को संसाधित नहीं करेगा, लेकिन सभी मान <5 को संसाधित करेगा।

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

कौन सा पुनरावृत्तियों? समग्र पुनरावृत्ति काउंटर? या प्रति थ्रेड? मुझे यकीन है कि यह प्रति धागा है। कृपया अनुमोदन करें।

यह सूचकांक समांतर में पारित किया जा रहा है। के लिए। ब्रेक() आइटम संसाधित होने से रोक नहीं पाएंगे, लेकिन यह गारंटी प्रदान करता है कि 100 तक की सभी वस्तुओं को संसाधित किया जाता है, लेकिन 100 से ऊपर की वस्तुओं को संसाधित किया जा सकता है या नहीं।

क्या मैं सही हूँ? यही कारण है कि मुझे अपने उदाहरण में 5 से अधिक तत्व क्यों मिलते हैं?

हां। यदि आप दिखाए गए विभाजनकर्ता का उपयोग करते हैं, जैसे ही आप Break() पर कॉल करते हैं, तो आप जिस स्थान को तोड़ते हैं उससे परे आइटम अब निर्धारित नहीं होंगे। हालांकि, आइटम (जो संपूर्ण विभाजन है) पहले ही निर्धारित किया जाएगा पूरी तरह से संसाधित हो जाएगा। आपके उदाहरण में, इसका मतलब है कि आप हमेशा सभी 1000 वस्तुओं को संसाधित करने की संभावना रखते हैं।

जब मैं वास्तव में तोड़ सकता हूं (i == 5)?

आप हैं - लेकिन जब आप समांतर में भागते हैं, तो चीजें बदलती हैं।वास्तविक लक्ष्य क्या है? यदि आप केवल पहले 6 आइटम (0-5) को संसाधित करना चाहते हैं, तो आपको से पहले आइटम को प्रतिबंधित करना चाहिए जो आप LINQ क्वेरी या इसी तरह के माध्यम से उनके माध्यम से लूप करते हैं। इसके बाद आप Parallel.For या Parallel.ForEach में 6 आइटम को Break() और बिना किसी चिंता के संसाधित कर सकते हैं।

मेरा मतलब है, चलो! जब मैं ब्रेक() करता हूं, तो मैं चीजों को लूप को रोकना चाहता हूं। मैं लूप के लिए नियमित रूप से करता हूं।

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

+0

आपका मतलब है कि _Break() लूप को किसी भी मान को संसाधित नहीं करेगा जो उनके INDEX> 5_ .... सही है? –

+0

@RoyiNamir हां, तरह। आइटम अभी भी संसाधित किए जाएंगे यदि वे पहले से ही निर्धारित और शुरू हो चुके हैं, लेकिन कोई भी नई वस्तु संसाधित नहीं होगी। यदि आप 'समानांतर' हैं। '' में हैं, तो गणना में स्थान के पिछले आइटम जहां आप ब्रेक() को कॉल करते हैं, अब निर्धारित नहीं होंगे। –

+0

ब्रेक के संबंध में 'बनाम फोरैच 'में कोई अंतर है ??? –

6

तोड़ 0 से 1000

पाश की 100 वीं यात्रा के समानांतर में पाश-बार दोहराना के लिए एक की 100 वीं पुनरावृत्ति से कहा जाता है जरूरी नहीं कि (वास्तव में शायद नहीं) के साथ एक है सूचकांक 99.

आपके धागे एक अनिश्चित आदेश में भाग सकते हैं और चलाएंगे। जब। ब्रेक() निर्देश का सामना करना पड़ता है, तो कोई और लूप पुनरावृत्ति शुरू नहीं होगी। वास्तव में जब ऐसा होता है तो किसी विशेष रन के लिए थ्रेड शेड्यूलिंग के विनिर्देशों पर निर्भर करता है।

मैं दृढ़ता से पढ़ने

Patterns of Parallel Programming

(Microsoft से मुक्त पीडीएफ)

डिजाइन फैसले और डिजाइन तालमेल कि TPL में चला गया को समझने के लिए सलाह देते हैं।

4

कौन सा पुनरावृत्तियों? समग्र पुनरावृत्ति काउंटर? या प्रति थ्रेड?

निर्धारित सभी पुनरावृत्तियों (या अभी तक निर्धारित किए जाने के लिए) बंद करें।

याद रखें कि प्रतिनिधि आदेश से बाहर हो सकता है, इस बात की कोई गारंटी नहीं है कि i == 5 निष्पादन के लिए छठा होगा, बल्कि दुर्लभ मामलों को छोड़कर यह मामला होने की संभावना नहीं है।

प्रश्न 2: क्या मैं सही हूँ?

नहीं, शेड्यूलिंग इतना सरल नहीं है। इसके बजाय सभी कार्यों को कतारबद्ध किया गया है और फिर कतार संसाधित की जाती है। लेकिन थ्रेड प्रत्येक अपनी कतार का उपयोग तब तक करते हैं जब तक वे खाली नहीं होते हैं जब वे अन्य धागे से चोरी करते हैं। इससे भविष्यवाणी करने का कोई तरीका नहीं है कि कौन सा धागा किस प्रतिनिधि को संसाधित करेगा।

यदि प्रतिनिधि पर्याप्त रूप से तुच्छ हैं तो सभी को मूल कॉलिंग थ्रेड पर संसाधित किया जा सकता है (कोई अन्य थ्रेड को काम चोरी करने का मौका नहीं मिलता है)।

प्रश्न 3: जब मैं वास्तव में तोड़ता हूं (i == 5)?

यदि आप रैखिक (विशिष्ट) प्रसंस्करण चाहते हैं तो समवर्ती रूप से उपयोग न करें।

Break सट्टा निष्पादन का समर्थन करने के लिए विधि है: विभिन्न तरीकों का प्रयास करें और जैसे ही कोई भी पूरा हो जाए।

+0

* यदि आप रैखिक (विशिष्ट) प्रसंस्करण चाहते हैं तो समवर्ती रूप से उपयोग न करें। * ... सत्य, लेकिन ... कोई यह सुनिश्चित कर सकता है कि काम का एक वर्ग समानांतर में होता है, काम एक आवश्यक बिंदु पर सिंक्रनाइज़ किया जाता है, फिर अतिरिक्त कार्य एक समान आवश्यक सिंक पॉइंट इत्यादि तक समानांतर में किया जाता है। बस यह कहना चाहते हैं कि आपका सही कथन उस प्रकार के पैटर्न के लिए जगह छोड़ देता है । –

+0

@EricJ। सच है, लेकिन इस सवाल में कोई सबूत नहीं है कि यह काम के दो अन्य टुकड़ों के बीच सिंक्रनाइज़ेशन का एक बिंदु है (और 'समांतर' के लिए अक्सर इसके लिए गलत प्रारंभ बिंदु होगा)। इसके बजाय था क्यू समझने की एक महत्वपूर्ण कमी के बारे में है कि 'समांतर' के लिए 'अतिरिक्त जादू के साथ लूप के लिए "नहीं है। – Richard

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