2015-01-19 17 views
11

की प्रगति का ट्रैक रखें मेरे पास map ऑपरेशन है (जो वास्तव में parMapControl.Parallel.Strategies से समानांतर में चलाया जाता है) इसमें काफी समय लगता है। यह देखते हुए कि मुझे पता है कि फ़ंक्शन को कितनी बार लागू किया गया है (n इस संदर्भ में), मैं आसानी से कैसे प्रदर्शित कर सकता हूं, प्रत्येक बार कुछ समय में, n अनुप्रयोगों में से कितने मूल्यांकन किए गए हैं?'मानचित्र'

स्पष्ट समाधान मानचित्र मानचित्रण समारोह के अंदर कुछ putStr के साथ एक mapM बनाने के लिए होगा, लेकिन है कि होगा:

  • दक्षता के एक अनावश्यक राशि लेने के एक में हर एक बार स्थिति नमूना
  • नहीं जबकि लेकिन हर अनुप्रयोगों में
  • मूल रूप से समानांतरवाद के संदर्भ में एक नियतात्मक एल्गोरिदम के बारे में सभी अच्छी चीजों को दूर

तो, क्या इस जानकारी का ट्रैक रखने का कोई तरीका है, कि मुझे याद आ रही है, जो इन समस्याओं से बचाती है?

+2

रोमानियाई में जाहिर तौर पर "चैंपियनशिप" अर्थ के अलावा, "कैंपियोनेट" का क्या अर्थ है? – dfeuer

+2

आप 'monad-par' पैकेज को देखना चाहते हैं। ऐसा लगता है कि आप कहां देख रहे हैं, लेकिन 'Control.Monad.Par.IO' दर्द को थोड़ा कम कर सकता है। यह कल्पना की जा सकती है कि आप थ्रेडस्कोप को जाने वाले गुओ के प्रकार में हुक कर सकते हैं, लेकिन मुझे संदेह है कि आपको वह वही देगा जो आप चाहते हैं। थ्रेड रिपोर्ट पूर्ण होने के लिए एक और विकल्प 'ट्रेस' या 'असुरक्षितफॉर्मियो' जैसे कुछ भयानक और असुरक्षित उपयोग करना हो सकता है। मुझे लगता है कि आवश्यक समस्या यह है कि "इस तरह के धागे अभी तक खत्म हो गए हैं?" एक प्रश्न नहीं है जो शुद्ध संदर्भ में समझ में आता है। – dfeuer

+0

आपको 'पैरामैप' प्रकार जोड़ना चाहिए, या उल्लेख करना चाहिए कि यह 'Control.Parallel.Strategies' से है या नहीं। – Zeta

उत्तर

2

उत्पादन में आप शायद का पता लगाने का उपयोग करना चाहिए नहीं और आईओ की आवश्यकता होगी, की जटिलताओं से निपटने के लिए मजबूर किया जाता है, लेकिन परीक्षण के लिए आप संशोधित कर सकता है parMap की परिभाषा जब अन्य पैरामीटर कह लेने के लिए एक गिनती फेंकना:

import Control.Monad (sequence) 
import Control.Parallel.Strategies (Strategy, using, rseq, rparWith, parMap) 
import Debug.Trace (traceShow) 
import System.IO (hFlush, hSetBuffering, BufferMode(NoBuffering), stdout) 

evalList' :: Integer -> Strategy a -> Strategy [a] 
evalList' t s as = sequence $ foldr f [] $ zip as [1..] 
    where f (a, n) ss | n `mod` t == 0 = s (traceShow n a):ss 
        | otherwise  = s a:ss 

parList' :: Integer -> Strategy a -> Strategy [a] 
parList' t s = evalList' t (rparWith s) 

parMap' :: Integer -> Strategy b -> (a -> b) -> [a] -> [b] 
parMap' t s f xs = map f xs `using` parList' t s 

-- some work to do 
fib :: Integer -> Integer 
fib 0 = 1 
fib 1 = 1 
fib n = fib (n-1) + fib(n-2) 

main = do hSetBuffering stdout NoBuffering 
      print $ sum (parMap' 1000 rseq (fib.(+20).(`mod` 5)) ([1..10000]::[Integer])) 

यदि प्रत्येक सूची तत्व द्वारा दिए गए कार्य संकुल छोटे हो जाते हैं, तो आप इसके अनुसार parListChunk को अनुकूलित कर सकते हैं।

0

कोई timeout का उपयोग करके इस व्यवहार को तैयार करने का प्रयास कर सकता है।

seconds :: Int 
seconds = 1000000 

progress :: [a] -> IO() 
progress [] = return() 
progress [email protected](x:xs) = 
    do r <- timeout (5 * seconds) x -- 5s 
    threadDelay (2 * seconds)  -- 2s more delay 
    case r of 
     Nothing -> progress l -- retry 
     Just y -> do putStrLn "one done!" 
        progress xs 

सावधान रहें क्योंकि मुझे डर है कि timeout गणना निरस्त किया जा रहा है। यदि कोई अन्य धागा है जो x का मूल्यांकन करता है जो ठीक होना चाहिए, लेकिन यदि यह एकमात्र धागा है तो यह 5 मिनट पर्याप्त नहीं होने पर जीवित रहने का कारण बन सकता है।

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