मुझे नहीं लगता कि सूची इसके लिए सही डेटा प्रकार है। चूंकि यह सिर्फ एक लिंक की गई सूची है, इसलिए डेटा को अनुक्रमिक रूप से एक्सेस किया जाएगा। यद्यपि आप समानांतर में वस्तुओं का मूल्यांकन कर सकते हैं, आप कमी चरण में ज्यादा लाभ नहीं उठाएंगे। क्या तुम सच में एक सूची की जरूरत है, मुझे लगता है कि सबसे अच्छा समारोह सिर्फ
parFold f = foldl1' f . withStrategy (parList rseq)
या शायद
parFold f = foldl1' f . withStrategy (parBuffer 5 rseq)
तो कमी कदम जटिल है, यदि आप एक लाभ इस तरह सूची subdividing द्वारा प्राप्त कर सकते हैं होगा:
parReduce f = foldl' f mempty . reducedList . chunkList . withStrategy (parList rseq)
where
chunkList list = let (l,ls) = splitAt 1000 list in l : chunkList ls
reducedList = parMap rseq (foldl' f mempty)
मैं अपने डेटा संभालने की स्वतंत्रता लिया है, mempty के लिए एक Monoid
है अगर यह संभव नहीं है कि आप या तो अपने स्वयं के खाली प्रकार के साथ mempty जगह ले सकता है, या बुरा मामले उपयोग foldl1'
।
यहां उपयोग में Control.Parallel.Strategies
से दो ऑपरेटर हैं। parList
समानांतर में सूची के सभी आइटमों का मूल्यांकन करता है। उसके बाद, chunkList
सूची को 1000 तत्वों के हिस्सों में विभाजित करता है। उन हिस्सों में से प्रत्येक को parMap
द्वारा समानांतर में कम किया जाता है।
तुम भी वास्तव में कैसे काम वितरित किया जाता है पर निर्भर करता है
parReduce2 f = foldl' f mempty . reducedList . chunkList
where
chunkList list = let (l,ls) = splitAt 1000 list in l : chunkList ls
reducedList = parMap rseq (foldl' f mempty)
कोशिश कर सकते हैं, इनमें से एक दूसरों की तुलना में अधिक कुशल हो सकता है।
यदि आप डेटा संरचना का उपयोग कर सकते हैं जिसमें इंडेक्सिंग के लिए अच्छा समर्थन है (ऐरे, वेक्टर, मैप इत्यादि), तो आप कमी चरण के लिए बाइनरी उपविभाग कर सकते हैं, जो शायद समग्र रूप से बेहतर होगा।
जैसा कि लोगों ने नोट किया है, सूची रिकर्सिव समांतर विभाजन के लिए एक खराब डेटा संरचना है। आप किले की भाषा में कुछ प्रकार के बाइनरी पेड़/रस्सी संरचना चाहते हैं: http://labs.oracle.com/projects/plrg/Publications/ICFPAugust2009Steele.pdf – sclv