【发布时间】:2018-03-16 12:23:20
【问题描述】:
我试图从给定的数字列表中找到素数。
到目前为止,我有一段代码可以工作,但是如果我取消注释某些行并注释其他一些行,我看不出速度有任何差异。
我几乎可以肯定我必须在单独的线程中强制评估,因为我认为我启动线程但由于懒惰而没有在那里评估代码。但我找不到强制进行评估的方法。我正在根据示例here 工作。所以我创建了函数parMap 和strMap,它们是并行映射和严格的[并行] 映射。在parMap 中有 2 行注释,因此如果您取消注释它们,并注释掉当前未注释的其他 4 行,那么您不会注意到速度上的任何差异,尽管它应该是非并行的并且速度较慢。我现在也忽略了 main 函数中的程序参数。
所以基本上我的问题是 - 是否有可能实现,对于列表中提供给 parMap 的每个数字,都会产生一个新线程,因此一切工作得更快?
代码如下:
module W7T5
(
main
) where
import Control.Concurrent
import Control.Parallel (par, pseq)
import System.Environment
main = do
args' <- getArgs
let
-- args = map (\x -> read x :: Int) args'
args = [2000000..2000200]
tfPrime = parMap isPrime' args
-- tfPrime = strMap isPrime' args
argsNtf = zip args tfPrime
primes' = filter (\(num, tfPrime) -> tfPrime) argsNtf
primes = map fst primes'
putStrLn ("Init list: " ++ show args)
putStrLn ("Primes : " ++ show primes)
-- Map in parallel
parMap :: NFData a => (a -> b) -> [a] -> [b]
parMap _ [] =
[]
--parMap f (x:xs) = -- sadly without any parallelisation it's not slower
-- (f x) :parMap f xs
parMap f (x:xs) =
par r (r:parMap f xs)
where
r = f x
-- Map in parallel strictly
strMap :: (a -> b) -> [a] -> [b]
strMap f xs =
forceList xs `seq` map f xs
forceList :: [a] -> ()
forceList (x:xs) =
xs `pseq` forceList xs
forceList _ =
()
isPrime' :: Int -> Bool
isPrime' 0 = True
isPrime' 1 = True
isPrime' 2 = True
isPrime' num =
all (/=0) [mod num x | x <- [2..(num-1)]]
你可以运行程序
runhaskell W7T5.hs 1 2 3 4
【问题讨论】:
-
你确定你使用超过 1 个线程吗? ghc 有一个选项“-thread”,用于编译超过 1 个线程。编译后的程序采用“+RTS -N2”选项在两个内核上运行。不知道如何使用 runhaskell 来执行此操作。
标签: haskell parallel-processing