2012-11-24 16 views
7

मैं कई (> 1000) लंबे समय तक चलने वाले कार्यों को निष्पादित करने के लिए F # में टास्क समांतर लाइब्रेरी (टीपीएल) का उपयोग करना चाहता हूं।टीपीएल समांतर। लंबे समय तक चलने वाले कार्यों के साथ

Parallel.For(1, numberOfSets, fun j -> 
    //Long running task here 
    ) 

जब मैं इस शुरू ऐसा लगता है कि नेट लगातार उन दोनों के बीच एक बार में कार्यों के आरंभ करता है और बाउंस: यहाँ मेरे वर्तमान कोड है। बेहतर होगा अगर यह किसी कार्य पर तब तक रहे जब तक कि इसे अगले स्थान पर जाने से पहले नहीं किया जाता। यह संदर्भ स्विचिंग को कम करेगा।

शेड्यूलर को संकेत देने का कोई तरीका है? मुझे पता है कि संकेत प्रदान करना संभव है लेकिन मुझे स्पष्ट उदाहरण नहीं मिल रहे हैं या शेड्यूलर पहले से ही इसके बारे में स्मार्ट है और यह सिर्फ मेरी धारणा है कि बहुत सारे संदर्भ स्विच होते हैं। सहायता के लिए धन्यवाद!

उत्तर

8

हमें एक समान समस्या थी - एफ # की बजाय सी # का उपयोग करके, लेकिन पुस्तकालय समान हैं। समाधान समानांतरवाद की डिग्री को सीमित करने गया था:

ParallelOptions parallelOptions = new ParallelOptions(); 
parallelOptions.MaxDegreeOfParallelism = 16; 
Parallel.For(0, n, parallelOptions, i => { 
    . . . 
}); 

16 हमारे कार्यों के लिए अच्छी तरह से काम - आप को देखने के लिए जो मूल्य आपके मामले में बेहतर है प्रयोग करना चाहिए।

+0

+1, मेरे से सेकंड तेज :) :) –

+0

क्या MaxDegreeOfParallelism आपकी मशीन पर कोर की संख्या पर निर्भर करता है? –

+0

@ वालहुड: शायद हाँ यदि कार्य सीपीयू-बाध्य है, तो यदि कार्य आईओ-बाउंड (फ़ाइल प्रोसेसिंग, डीबी तक पहुंच) है तो शायद नहीं। हमारे मामले में यह मान सामान्य परिस्थितियों में 2/4 कोर पर ठीक काम करता था, कुछ और परिष्कृत प्रयास करने का कोई वास्तविक कारण नहीं था - यह ऐसा प्रोग्राम नहीं है जो उदाहरण के लिए 16 कोर सुपर-मशीन पर चलने की संभावना है। – MiMo

5

मेरे अनुभव से, बड़ी संख्या में कार्यों के लिए MaxDegreeOfParallelism को Environment.ProcessorCount पर रैखिक रूप से बाध्य करना बेहतर है।

let options = ParallelOptions() 
options.MaxDegreeOfParallelism <- Environment.ProcessorCount * 2 

Parallel.For(0, n, options, 
      (fun i -> (* Long running task here *))) |> ignore 

आप एफ # में समानांतर प्रोग्रामिंग के साथ काम कर रहे हैं के बाद से, कृपया एक नज़र उत्कृष्ट पुस्तक "Parallel Programming with Microsoft .NET", विशेष रूप से अध्याय पर ले:

यहाँ करने के लिए @ एफ # वाक्य रचना में Mimo के एक इसी तरह की एक कोड टुकड़ा है "Parallel Loops" पर। @ टोमास ने अपने नमूने का अनुवाद एफ # में किया है और वे here उपलब्ध हैं।

// initialize ranges with passed in loop arguments and expected number of workers 
int numExpectedWorkers = (parallelOptions.EffectiveMaxConcurrencyLevel == -1) ? 
    Environment.ProcessorCount : 
    parallelOptions.EffectiveMaxConcurrencyLevel; 

जहां तक ​​मेरा बता सकते हैं, डिफ़ॉल्ट कार्य अनुसूचक और डिफ़ॉल्ट ParallelOptions इस Environment.ProcessorCount करने का मूल्यांकन करती है,:

1

संदर्भ स्रोत को देखते हुए, यह कोड का निम्न भाग श्रमिकों की संख्या निर्धारित करता है प्रकट होता है इसलिए यह अजीब बात है कि प्रोसेसर को स्वयं गिनने के लिए MaxDegreeOfParallelism निर्दिष्ट करके आपको एक अलग व्यवहार मिल रहा है। मेरा सुझाव है कि आप यह सुनिश्चित करने के लिए डीबग करें कि वास्तव में एक अंतर है (आप लंबे समय तक चलने वाले कार्य के अंदर Thread.ManagedThreadId प्रिंट कर सकते हैं)।

+0

इसमें काफी अंतर था। जब मैंने मैक्स कंसुरेंसी निर्दिष्ट की तो यह प्रति कोर एक समय में केवल एक कार्य खुल जाएगा। जब मैंने इसे निर्दिष्ट नहीं किया, तो यह सभी कार्यों को एक साथ खोल देगा।यह केवल एक समय में एक पर काम किया हो सकता है लेकिन यह सब खुला है। मैं इस तथ्य से इसे कम कर रहा हूं कि मैं प्रत्येक कार्य के लिए टाइमर शुरू करता हूं। जब मैंने समांतरता निर्दिष्ट की तो प्रत्येक कार्य के लिए समय समान था। जब मैंने काम नहीं किया तो पूरा करने में बहुत लंबा समय लग सकता था। नीचे क्या चल रहा है, मुझे नहीं पता लेकिन वे मेरे अवलोकन थे। –

+0

शायद श्रमिकों की संख्या और 'मैक्सडेग्री ओफपेरेलिज्म' दो अलग-अलग चीजें हैं? मैं पुष्टि करता हूं कि @ वालहुड कहता है: जब मैक्सडेग्री ओफपेरेलिज्म 'सेट करते थे, तब हमारे पास 1000 कार्य होते थे, वे सभी समानांतर में शुरू होते थे और वे मशीन को चौंकाने लगे थे, समस्या 16 को सेट करने के लिए तय की गई थी (हमारा कार्य सीपीयू नहीं है लेकिन ज्यादातर डेटाबेस बाध्य है) – MiMo

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