2012-11-25 7 views
6

हास्केल प्रोग्राम में मल्टीथ्रेडिंग कार्यक्षमता जोड़ने का प्रयास करने के बाद, मैंने देखा कि प्रदर्शन में कोई सुधार नहीं हुआ है। इसका पीछा करते हुए, मुझे थ्रेडस्कोप से निम्नलिखित डेटा मिला:एक हास्केल प्रोग्राम में बहुभाषी प्रदर्शन प्रोफाइलिंग - समांतर रणनीतियों का उपयोग करके कोई गति नहीं

Graph 1 ग्रीन चलने का संकेत देता है, और नारंगी कचरा संग्रह है। Graph 2 Graph 3 यहां ऊर्ध्वाधर हरी बार स्पार्क निर्माण का संकेत देते हैं, नीले रंग के बार समानांतर जीसी अनुरोध होते हैं, और हल्के नीले रंग के सलाखों में धागा निर्माण होता है। Graph 4 लेबल हैं: बनाया चिंगारी, समानांतर जीसी का अनुरोध धागा एन बनाने, और टोपी 2.

औसत पर से चिंगारी चोरी, मैं केवल 4 कोर के ऊपर लगभग 25% गतिविधि हो रही है, जिस पर कोई सुधार है सभी सिंगल थ्रेडेड प्रोग्राम पर।

बेशक, प्रश्न वास्तविक कार्यक्रम के विवरण के बिना शून्य हो जाएगा। अनिवार्य रूप से, मैं एक ट्रैवर्सेबल डेटा स्ट्रक्चर (उदाहरण के लिए एक पेड़) बनाता हूं, और उसके बाद एक फ़ंक्शन को फ़ैमप करता हूं, इससे पहले कि इसे एक छवि लेखन दिनचर्या में खिलाया जाता है (कार्यक्रम चलाने के अंत में अनजाने एकल-थ्रेडेड सेगमेंट को समझाता है, पिछले 15s) । फ़ंक्शन के निर्माण और fmapping दोनों को चलाने के लिए काफी समय लगता है, हालांकि दूसरा थोड़ा और अधिक।

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

यहाँ कुछ अतिरिक्त आँकड़े (एक ही कार्यक्रम का एक अलग रन के लिए) इस प्रकार हैं:

5,702,829,756 bytes allocated in the heap 
    385,998,024 bytes copied during GC 
     55,819,120 bytes maximum residency (8 sample(s)) 
     1,392,044 bytes maximum slop 
      133 MB total memory in use (0 MB lost due to fragmentation) 

            Tot time (elapsed) Avg pause Max pause 
    Gen 0  10379 colls, 10378 par 5.20s 1.40s  0.0001s 0.0327s 
    Gen 1   8 colls,  8 par 1.01s 0.25s  0.0319s 0.0509s 

    Parallel GC work balance: 1.24 (96361163/77659897, ideal 4) 

         MUT time (elapsed)  GC time (elapsed) 
    Task 0 (worker) : 0.00s (15.92s)  0.02s ( 0.02s) 
    Task 1 (worker) : 0.27s (14.00s)  1.86s ( 1.94s) 
    Task 2 (bound) : 14.24s (14.30s)  1.61s ( 1.64s) 
    Task 3 (worker) : 0.00s (15.94s)  0.00s ( 0.00s) 
    Task 4 (worker) : 0.25s (14.00s)  1.66s ( 1.93s) 
    Task 5 (worker) : 0.27s (14.09s)  1.69s ( 1.84s) 

    SPARKS: 595854 (595854 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled) 

    INIT time 0.00s ( 0.00s elapsed) 
    MUT  time 15.67s (14.28s elapsed) 
    GC  time 6.22s ( 1.66s elapsed) 
    EXIT time 0.00s ( 0.00s elapsed) 
    Total time 21.89s (15.94s elapsed) 

    Alloc rate 363,769,460 bytes per MUT second 

    Productivity 71.6% of total user, 98.4% of total elapsed 

मुझे यकीन है कि क्या अन्य उपयोगी जानकारी मैं जवाब देने की सहायता के लिए दे सकते हैं नहीं कर रहा हूँ। प्रोफाइलिंग कुछ भी दिलचस्प नहीं बताती है: यह एक कोर आईडी आंकड़ों के समान है, जैसा कि उपरोक्त से अपेक्षित अनुमानित आईडीईएल 75% समय लेता है।

क्या हो रहा है जो उपयोगी समांतरता को रोक रहा है?

+0

आप कोड, या कोड के कम से कम प्रासंगिकता का है, कहीं न कहीं है? – shachaf

+0

एक बार जब मैं प्रोग्राम से संबंधित कोड निकालता हूं, तो जो कुछ भी बचा है, वह बिल्कुल सही वर्णन है जो मैंने ऊपर उल्लिखित किया है, इसलिए मुझे कोई वास्तविक कोड शामिल करने में मदद नहीं मिली। मैं यह भी नहीं देखता कि यह कितना महत्वपूर्ण है कि मैं जिस फ़ंक्शन का उपयोग कर रहा हूं, वह तब तक है जब तक यह शुद्ध है (जो यह है)। यह समानांतर होना चाहिए चाहे कोई फर्क नहीं पड़ता कि भले ही ट्रैवर्सबल संरचना का निर्माण संभव न हो। – Will

+0

एक छोटा रेपो बनाएँ। शायद, आप खुद को ऐसा करने में समस्या की खोज करेंगे। यदि नहीं, तो हम रेपो को देख सकते हैं। – usr

उत्तर

4

क्षमा करें कि मैं उत्तरदाताओं की सहायता के लिए समय पर कोड प्रदान नहीं कर सका। इस मुद्दे के सही स्थान को उलझाने में मुझे कुछ समय लगा।

समस्या इस प्रकार थी: मैं traversable डेटा संरचना

structure :: T a 

पर एक समारोह

f :: a -> S b 

fmapping गया था, जहां एस और टी दो traversable functors हैं।

तब, जब parTraversable का उपयोग कर, मैं गलती से

Compose (fmap f structure) `using` parTraversable rdeepseq 

Compose $ fmap f structure `using` parTraversable rdeepseq 

के बजाय

लिख रहा था तो मैं गलत तरीके से traversable उदाहरण उपयोग कर रहा था लिखें टीएस बहु सूत्रण (करने के लिए Data.Functor का उपयोग कर .Compose)।

(यह लगता है कि उसे पकड़ने के लिए आसान किया गया है चाहिए, लेकिन यह मुझे कुछ समय लिया कोड से ऊपर गलती निकालने के लिए!)

यह अब काफी बेहतर लग रहा है!

Graph 1

Graph 2

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