为什么`par`只使用一个核心但速度更快?

xzh*_*zhu 2 haskell

我正在尝试测试parallel包,特别是par功能.我写了一个简单的程序来测试并行性是否会加速顺序程序.

所以在这里我写了两个脚本,第一个顺序:

import Control.Parallel

n = 600000000

main = print $ pseq (mod (sum [1..n]) 5) (mod (sum [1..n]) 5)
Run Code Online (Sandbox Code Playgroud)

第二个并行:

import Control.Parallel

n = 600000000

main = print $ par (mod (sum [1..n]) 5) (mod (sum [1..n]) 5)
Run Code Online (Sandbox Code Playgroud)

我使用ghc -O2并运行它们编译每个,然后使用GNU测量运行时间time.这是我得到的:

顺序:

User time (seconds): 13.79
System time (seconds): 0.04
Percent of CPU this job got: 99%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:13.85
Run Code Online (Sandbox Code Playgroud)

平行:

User time (seconds): 6.89
System time (seconds): 0.05
Percent of CPU this job got: 99%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:06.97
Run Code Online (Sandbox Code Playgroud)

这很有趣但令人困惑:为什么并行版本的速度提高了两倍,但只使用了一个核心?

Dan*_*ner 8

为什么它只使用一个核心?

因为您使用了非线程运行时.编译-threaded以利用花哨的新线程运行时.但是由于第二个问题的答案,这对于这个微基准测试无法帮助你:你只编写了一个核心的计算值.

它为什么变得更快?

因为它计算的东西较少:因为第一个参数par从未被第二个参数使用,所以它会被塞进一个永远不会被要求的火花中,因此永远不会被迫去做它的工作.另一方面,pseq 总是做第一个参数所需的工作,即使第二个参数没有使用该值.