2010-10-18 19 views
16

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

मेरा प्रश्न

: आप समानांतर एक्सटेंशन का उपयोग कर रहे हैं, और यदि ऐसा है तो, तो कैसे?

मेरा नाम स्टीफन Toub है और मैं माइक्रोसॉफ्ट में पैरलल कंप्यूटिंग मंच टीम पर कर रहा हूँ। हम समानांतर एक्सटेंशन के लिए जिम्मेदार समूह हैं। मैं हमेशा इस बारे में सुनने में रूचि रखता हूं कि कैसे डेवलपर्स समांतर एक्सटेंशन का उपयोग कर रहे हैं (उदाहरण के लिए समानांतर। फॉर, पीआईएलक्यू, कंसूरेंट डिक्शनरी इत्यादि), आपके पास सकारात्मक अनुभव, आपके नकारात्मक अनुभव, भविष्य के लिए अनुरोध अनुरोध, और इसलिए पर।
यदि आप इस तरह की जानकारी साझा करने के लिए तैयार हो जाएगा, कृपया निजी तौर पर ईमेल के माध्यम से stoub at microsoft dot com पर करते हैं, या तो यहाँ इस सवाल के जवाब के रूप या मेरे लिए।

मैं बहुत तुम से सुनने के लिए उत्सुक हूं।

अग्रिम धन्यवाद!

+2

चूंकि इस प्रश्न का एक सही जवाब नहीं हो सकता है, मुझे डर है कि यह स्टैक ओवरफ्लो के लिए उपयुक्त नहीं है। चूंकि आप एमएस टीम में हैं, इसलिए मैं बंद करने के लिए वोट नहीं दूंगा, लेकिन शायद अन्य इच्छाशक्ति होगी। प्रोग्रामर.स्टैकएक्सchange.com और मेटा.स्टैकओवरफ्लो डॉट कॉम पर आपको बेहतर भाग्य हो सकता है। इसके अलावा आप प्रश्न को "सामुदायिक विकी" के रूप में चिह्नित कर सकते हैं, इसलिए वोट प्रतिनिधि के प्रति/प्रतिबिंबित नहीं होते हैं और यह बंद होने की संभावना कम होती है। –

+0

ठीक है। धन्यवाद, सैम। साइट का दुरुपयोग करने के लिए माफ़ी। -स्टेफेन –

+2

@ स्टीफन टब, 12 घंटे और शून्य वोट बंद करने के लिए। ऐसा लगता है कि लोगों को यह बुरा नहीं लगता है। हालांकि कोई जवाब नहीं है। –

उत्तर

0

मैं अपने प्रोजेक्ट MetaSharp पर उपयोग किया गया है। मेरे पास डीएसएल के लिए एक एमएसबिल्ड आधारित संकलन पाइपलाइन है और एक चरण प्रकार कई मंचों में से कई है। एम: एम मंच का उपयोग करता है .एसएपरेल। फॉरएल (...)।

यहाँ snippet है:

protected sealed override IEnumerable<IContext> Process() 
{ 
    if (this.Input.Count() > 1) 
    { 
     this.Input 
      .AsParallel<IContext>() 
      .ForAll(this.Process); 
    } 
    else if (this.Input.Any()) 
    { 
     this.Process(this.Input.Single()); 
    } 

    return this.Input.ToArray(); 
} 
+4

मैं इस की सिफारिश करता हूं। इनपुट। स्किप (1) .एनी() ', ताकि आप दूसरे इनपुट को मारने के बाद गिनती रोक सकें । – StriplingWarrior

+1

मतलब: इसे प्रतिस्थापित करें। इनपुट। गणना()> 1 इसके साथ। इनपुट। स्किप (1) .एनी()। – dthorpe

+0

अच्छी कॉल! यही कारण है कि बहुत उपयोगी है। –

4

मैं नेस्ट Parallel.ForEach कॉल करने के लिए TPL उपयोग कर रहा हूँ। क्योंकि मैं इन कॉलों से शब्दकोशों तक पहुंचता हूं, मुझे ConcurrentDictionary का उपयोग करना पड़ता है।

  • ForEach के अंदर प्रतिनिधियों ज्यादा काम नहीं करते तो मैं बहुत समानांतरवाद नहीं मिलता है: हालांकि यह अच्छा है, मैं कुछ मुद्दे हैं। प्रणाली अपने अधिकांश समय धागे में शामिल होने लगता है। यह अच्छा होगा अगर यह पता लगाने का कोई तरीका था कि यह बेहतर समेकन क्यों नहीं कर रहा है और इसे बेहतर बना रहा है।

  • भीतरी ForEach पुनरावृत्तियों ConcurrentDictionary से अधिक उदाहरणों, जो प्रणाली शब्दकोश के लिए अपने समय प्रगणक की ज्यादा खर्च करने के लिए अगर मैं एक प्रगणक कैश नहीं जोड़ा था, कारण होता है।

  • मेरे ConcurrentDictionary उदाहरणों में से कई वास्तव में सेट हैं, लेकिन ConcurrentSet नहीं है इसलिए मुझे ConcurrentDictionary के साथ अपना स्वयं का कार्यान्वयन करना पड़ा।

  • ConcurrentDictionary वस्तु प्रारंभ वाक्य रचना का समर्थन नहीं करता तो मैं var dict = new ConcurrentDictionary<char, int> { { 'A', 65 } }; नहीं कह सकता भी है जिसका अर्थ है मैं वर्ग के सदस्यों को ConcurrentDictionary शाब्दिक नहीं सौंप सकते।

  • कुछ ऐसे स्थान हैं जहां मुझे ConcurrentDictionary में एक कुंजी देखना है और यदि यह अस्तित्व में नहीं है तो मूल्य बनाने के लिए एक महंगी फ़ंक्शन कॉल करें। यह अच्छा होगा यदि वहाँ है कि एक addValueFactory लेती है, ताकि मूल्य केवल गणना की जा सकती है, तो कुंजी मौजूद नहीं है GetOrAdd की एक अधिभार थे। इसे .AddOrUpdate(key, addValueFactory, (k, v) => v) के साथ अनुकरण किया जा सकता है लेकिन यह प्रत्येक लुकअप के लिए एक अतिरिक्त प्रतिनिधि कॉल का ओवरहेड जोड़ता है।

+0

मुझे लगता है कि आप घोंसले का उपयोग किए बिना बेहतर हो सकते हैं। सीपीयू की तुलना में अधिक कार्यों को बनाने का कोई कारण नहीं है - कम से कम बहुत कुछ नहीं। मैं सराय समांतर से छुटकारा पाने की सलाह दूंगा। फॉरएच। –

+0

जो एच: आंतरिक लोग वास्तव में प्रक्रिया को 5-10% तेज बनाते हैं। – Gabe

1

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

private static readonly char[] delimiters = { ' ', '.', ',', ';', '\'', '-', ':', '!', '?', '(', ')', '<', '>', '=', '*', '/', '[', ']', '{', '}', '\\', '"', '\r', '\n' }; 
private static readonly Func<string, string> theWord = Word; 
private static readonly Func<IGrouping<string, string>, KeyValuePair<string, int>> theNewWordCount = NewWordCount; 
private static readonly Func<KeyValuePair<string, int>, int> theCount = Count; 

private static void Main(string[] args) 
{ 
    foreach (var wordCount in File.ReadAllText(args.Length > 0 ? args[0] : @"C:\DEV\CountUniqueWords\CountUniqueWords\Program.cs") 
     .Split(delimiters, StringSplitOptions.RemoveEmptyEntries) 
     .AsParallel() 
     .GroupBy(theWord, StringComparer.OrdinalIgnoreCase) 
     .Select(theNewWordCount) 
     .OrderByDescending(theCount)) 
    { 
     Console.WriteLine(
      "Word: \"" 
      + wordCount.Key 
      + "\" Count: " 
      + wordCount.Value); 
    } 

    Console.ReadLine(); 
} 

private static string Word(string word) 
{ 
    return word; 
} 

private static KeyValuePair<string, int> NewWordCount(IGrouping<string, string> wordCount) 
{ 
    return new KeyValuePair<string, int>(
     wordCount.Key, 
     wordCount.Count()); 
} 

private static int Count(KeyValuePair<string, int> wordCount) 
{ 
    return wordCount.Value; 
} 
+1

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

+1

अच्छा, चलो इसे देखते हैं, आदमी! –

+0

@ थॉमस - आपको शायद जेसी की टिप्पणी के लिए अधिसूचना नहीं मिली। इस टिप्पणी को उस अधिसूचना के रूप में कार्य करने दें। – Greg

0

हम इसे बड़े पैमाने पर का उपयोग नहीं करते, लेकिन यह निश्चित आ गया है सिद्धहस्त में।

मैं Parallel.Invoke() कॉल में कुछ अधिक समय-गहन कदमों को लपेटकर अपने लगभग लंबे समय तक चलने वाले यूनिट परीक्षणों के चलने का समय लगभग 1/3 उनके मूल समय को कम करने में सक्षम था।

मैं भी परीक्षण धागे की सुरक्षा के लिए समानांतर लाइब्रेरी का उपयोग कर प्यार करते हैं। मैं पकड़ लिया और इस तरह कोड कुछ के साथ Ninject साथ सूत्रण मुद्दों के एक जोड़े की रिपोर्ट की है:

var repositoryTypes = from a in CoreAssemblies 
        from t in a.GetTypes() 
        where t.Name.EndsWith("Repository") 
        select t; 
repositoryTypes.ToList().AsParallel().ForAll(
    repositoryType => _kernel.Get(repositoryType)); 

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

0

मैं एक ConcurrentDictionary का उपयोग कर रहा हूं जो 100 मिलियन + आइटम स्टोर करता है। मेरा आवेदन उस पल में लगभग 8 जीबी मेमोरी का उपयोग करता है। ConcurrentDictionary तब फैसला करता है कि वह एक और जोड़ें पर बढ़ना चाहता है। और यह स्पष्ट रूप से बहुत कुछ बढ़ना चाहता है (कुछ आंतरिक प्राइमा एल्गोरिदम) क्योंकि यह स्मृति से बाहर हो जाता है। यह 32 जीबी मेमोरी के साथ x64 पर है।

इसलिए मैं एक (समवर्ती) शब्दकोश का स्वत: regrow/मिलावत ब्लॉक करने के लिए एक बूलियन चाहते हैं। इसके बाद मैं बाल्टी के एक निश्चित सेट के साथ सृजन में शब्दकोश शुरू कर दूंगा (यह एक निश्चित क्षमता के समान नहीं है!)। और यह समय के साथ थोड़ा धीमा हो जाएगा क्योंकि एक बाल्टी में अधिक से अधिक आइटम हैं। लेकिन यह रीहाशिंग और स्मृति से बहुत जल्दी और अनावश्यक रूप से बाहर निकलने से रोक देगा।

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