【发布时间】:2020-06-17 22:28:21
【问题描述】:
我尝试用多核运行一些程序,结果有点困惑。
默认情况下,在下面的程序中排序需要 20 秒,当我使用 +RTS -N2 运行它时大约需要 16 秒,但使用 +RTS -N4 需要 21 秒!
为什么会这样?并且有没有每个额外内核变得更快的程序示例? (与教程中的其他程序有相似的结果)
以下是程序示例:
import Data.List
import Control.Parallel
import Data.Time.Clock.POSIX
qsort :: Ord a => [a] -> [a]
qsort (x:xs)
= let a = qsort $ filter (<=x) xs
b = qsort $ filter (>x) xs
in b `par` a ++ x:b
qsort [] = []
randomList :: Int -> [Int]
randomList n = take n $ tail (iterate lcg 1)
where lcg x = (a * x + c) `rem` m
a = 1664525
c = 1013904223
m = 2^32
main :: IO ()
main = do
let randints = randomList 5000000
t1 <- getPOSIXTime
print . sum $ qsort randints
t2 <- getPOSIXTime
putStrLn $ "SORT TIME: " ++ show (t2 - t1) ++ "\n"
【问题讨论】:
-
大问题。首先,懒惰使了解并行实际发生的事情变得有点棘手。您实际上并没有像您想象的那样并行执行。
-
您在时间测量中包括列表生成。您是否尝试过在启动计时器之前强制列表?
-
你也可以尝试添加
-A1000M,看看垃圾回收是否有很大的不同。也可以推荐一下threadscope程序,可以用来可视化。 -
@FyodorSoikin 我在列表中尝试了 deepseq,它减少了时间,但相互比较结果是相同的
-
@dfeuer 你能给我一个包含数组输入和输出的代码的链接吗?我很乐意尝试一下。您链接到的答案非常好,无论优化如何,它都永远不会是最佳的。我也不明白问这些问题的人。例如,我给了@crends 链接到我在 Haskell 中看到的最快的快速排序实现,它自然使用所有内核,我回复:“我不仅对性能感兴趣,而且对并行化感兴趣。”答案我尽管我提供的解决方案比接受的答案快 x1000,但未接受链接到。
标签: haskell