Haskell speculative parallel execution

大憨熊 提交于 2019-12-04 03:16:38

Ultimately, any solution will wind up using ForkIO under the hood because you want multiple transactions to be occurring in parallel. Even Conal's unamb works this way.

For the latter you probably want a more complicated monad that batches up and runs for a while before checking an MVar occasionally for a monotonically posted improving value, but the simplest answer to interleave (within one thread) is to just write a Partiality monad.

data Partial a = Return a | Partial (Partial a)

instance Monad Partial where
    return = Return
    Return a >>= f = f a
    Partial m >>= f = Partial (m >>= k)


run :: Partial a -> a
run (Partial m) = run m
run (Return a) = a

race :: Partial a -> Partial a -> Partial a
race (Return a) _ = a
race _ (Return b) = b
race (Partial m) (Partial n) = race m n

yield :: Partial ()
yield = Partial (Return ())

With an appropriate MonadFix instance to deal with recursion or liberally sprinkled 'yield' calls, you can perform both of your operations in the Partial monad and race them to obtain a deterministic result.

But in practice, if you want to get the full benefit of parallelism you'll want to update and check some kind of 'improving' MVar periodically.

Something like (off the cuff, sorry, no compiler handy!):

import Control.Concurrent.MVar (newMVar, readMVar)
import Control.Parallel.Strategies (using, parList)
import GHC.IOBase (unsafeDupablePerformIO, unsafePerformIO)

diag x = (x,x)

parMax :: (Bounded a, Ord a) => [a] -> a
parMax xs = unsafePerformIO $ do
    threshold <- newMVar minBound
    let optimize x = unsafeDupablePerformIO $
        x `seq` modifyMVar threshold (return . diag . max x)
    return . maximum $ map optimize xs `using` parList

Of course, that should be able to be rewritten to support any idempotent commutative monoid, not just max.

For the first question, Check out Conal Elliott's unamb: http://hackage.haskell.org/package/unamb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!