我无法在Haskell中完成并行计算。我只是尝试了一种非常简单的并行和非并行形式的计算,而非并行的计算速度提高了几秒钟。难道我做错了什么?任何想法为什么会这样?提前谢谢。
这是我的测试代码的并行版本:
-- par.hs
import Control.Parallel
a = sum [1, 3 .. 99999999]
b = sum [2, 4 .. 100000000]
main = (a `par` b) `pseq` print (a + b)
这是非并行版本:
-- nopar.hs
a = sum [1, 3 .. 99999999]
b = sum [2, 4 .. 100000000]
main = print (a + b)
但是当我尝试它时,并行化没有甚至是消极的影响:
➜ ghc par.hs
[1 of 1] Compiling Main ( par.hs, par.o )
Linking par ...
➜ ghc nopar.hs
[1 of 1] Compiling Main ( nopar.hs, nopar.o )
Linking nopar ...
➜ time ./par
5000000050000000
./par 35.02s user 12.83s system 92% cpu 51.501 total
➜ time ./nopar
5000000050000000
./nopar 31.33s user 6.44s system 98% cpu 38.441 total
答案 0 :(得分:4)
IIUC,@ Carl和@Zeta的评论组合解决了这个问题:
$ ghc -threaded -O2 par.hs && time ./par
50000005000000
real 0m2.303s
user 0m2.124s
sys 0m0.176s
$ ghc par.hs && ./par +RTS -N2
Linking par ...
par: the flag -N2 requires the program to be built with -threaded
par:
par: Usage: <prog> <args> [+RTS <rtsopts> | -RTS <args>] ... --RTS <args>
par:
par: +RTS Indicates run time system options follow
par: -RTS Indicates program arguments follow
par: --RTS Indicates that ALL subsequent arguments will be given to the
par: program (including any of these RTS flags)
$ ghc -threaded -O2 par.hs && time ./par +RTS -N2
50000005000000
real 0m1.572s
user 0m2.816s
sys 0m0.296s
要了解原因,请参阅Real World Haskell
的摘录默认情况下,GHC生成的程序只使用一个核心,即使我们编写显式并发代码也是如此。要使用多个内核,我们必须明确选择这样做。当我们生成可执行程序时,我们在链接时做出这个选择。 ...如果我们将
-threaded
选项传递给编译器,它会将我们的程序链接到线程运行时库。
和
我们可以在程序的命令行上将选项传递给GHC的运行时系统。在将控制权交给我们的代码之前,运行时扫描程序的参数以获取特殊命令行选项+ RTS。 ...线程运行时接受选项-N。这需要一个参数,它指定GHC的运行时系统应该使用的核心数。