haskell-为什么我的并行代码运行得很差?
发布时间:2022-08-26 09:37:13 243
相关标签:
我一直在尝试并行化Haskell代码,但速度越来越慢,所以我制作了一些示例代码来说明我的问题,这里是串行代码:
module Main where
import System.Environment
sumRangeSquares :: (Num a, Enum a) => a -> a -> a
sumRangeSquares start end = sum $ map (^2) [start .. end]
main :: IO ()
main = do
[start, end] <- map read <$> getArgs
print $ sumRangeSquares start end
编译时使用stack ghc -- -O2 -rtsopts -eventlog -threaded src/Main.hs
并与time ./src/Main 1 10000000
,大约在0.4秒内完成
现在,明显的平行对应物是:
module Main where
import Control.Parallel.Strategies
import System.Environment
sumRangeSquares :: (Num a, Enum a) => a -> a -> a
sumRangeSquares start end = sum $ parMap rseq (^2) [start .. end]
main :: IO ()
main = do
[start, end] <- map read <$> getArgs
print $ sumRangeSquares start end
以相同的方式编译并运行time ./src/Main 1 10000000 +RTS -N4 -lf -s
耗时6秒以上
以下是创建的日志-s
:
2,661,959,552 bytes allocated in the heap
1,891,228,032 bytes copied during GC
468,753,512 bytes maximum residency (12 sample(s))
307,102,616 bytes maximum slop
1226 MiB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 1837 colls, 1837 par 10.483s 2.705s 0.0015s 0.0080s
Gen 1 12 colls, 11 par 5.157s 1.391s 0.1159s 0.5573s
Parallel GC work balance: 26.09% (serial 0%, perfect 100%)
TASKS: 10 (1 bound, 9 peak workers (9 total), using -N4)
SPARKS: 10000000 (9998153 converted, 1847 overflowed, 0 dud, 0 GC'd, 0 fizzled)
INIT time 0.038s ( 0.038s elapsed)
MUT time 6.995s ( 2.158s elapsed)
GC time 15.639s ( 4.096s elapsed)
EXIT time 0.001s ( 0.005s elapsed)
Total time 22.673s ( 6.297s elapsed)
Alloc rate 380,577,209 bytes per MUT second
Productivity 30.8% of total user, 34.3% of total elapsed
real 0m6.374s
user 0m16.889s
sys 0m5.859s
下面是事件日志,如中所示threadscope Main.eventlog
.
如图所示,有很多空闲时间,所有四个 HEC 在相对相同的时间运行和空闲。此外,还有很多较长的空闲时间,以及不平衡的火花池和火花创建。
特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报