gpt4 book ai didi

haskell - 延迟 IO + 并行 : converting an image to grayscale

转载 作者:行者123 更新时间:2023-12-04 12:58:27 24 4
gpt4 key购买 nike

我正在尝试将并行性添加到将 .bmp 转换为灰度 .bmp 的程序中。我看到并行代码的性能通常会差 2-4 倍。我正在调整 parBuffer/分 block 大小,但似乎仍然无法推理。寻求指导。

这里使用的整个源文件:http://lpaste.net/106832

我们使用 Codec.BMP 读取由 type RGBA = (Word8, Word8, Word8, Word8) 表示的像素流。要转换为灰度,只需在所有像素上映射一个“luma”变换。

串行实现实际上是:

toGray :: [RGBA] -> [RGBA]
toGray x = map luma x

测试输入 .bmp 为 5184 x 3456 (71.7 MB)。

串行实现运行时间约为 10 秒,约为 550 纳秒/像素。 Threadscope 看起来很干净:

serial

为什么这么快?我想它有一些惰性字节字符串(即使 Codec.BMP 使用严格的字节字符串——这里是否发生了隐式转换?)和融合。

添加并行度

添加并行性的第一次尝试是通过 parList 。好家伙。该程序使用了约 4-5GB 内存,系统开始交换。

然后,我阅读了 Simon Marlow 的 O'Reilly 书中的“Parallelizing Lazy Streams with parBuffer”部分,并尝试了大尺寸的 parBuffer。这仍然没有产生理想的性能。 Spark 尺寸非常小。

然后我尝试通过对惰性列表进行分 block 来增加 Spark 大小,然后坚持使用 parBuffer 来实现并行性:
toGrayPar :: [RGBA] -> [RGBA]
toGrayPar x = concat $ (withStrategy (parBuffer 500 rpar) . map (map luma))
(chunk 8000 x)

chunk :: Int -> [a] -> [[a]]
chunk n [] = []
chunk n xs = as : chunk n bs where
(as,bs) = splitAt (fromIntegral n) xs

但这仍然不能产生理想的性能:
  18,934,235,760 bytes allocated in the heap
15,274,565,976 bytes copied during GC
639,588,840 bytes maximum residency (27 sample(s))
238,163,792 bytes maximum slop
1910 MB total memory in use (0 MB lost due to fragmentation)

Tot time (elapsed) Avg pause Max pause
Gen 0 35277 colls, 35277 par 19.62s 14.75s 0.0004s 0.0234s
Gen 1 27 colls, 26 par 13.47s 7.40s 0.2741s 0.5764s

Parallel GC work balance: 30.76% (serial 0%, perfect 100%)

TASKS: 6 (1 bound, 5 peak workers (5 total), using -N2)

SPARKS: 4480 (2240 converted, 0 overflowed, 0 dud, 2 GC'd, 2238 fizzled)

INIT time 0.00s ( 0.01s elapsed)
MUT time 14.31s ( 14.75s elapsed)
GC time 33.09s ( 22.15s elapsed)
EXIT time 0.01s ( 0.12s elapsed)
Total time 47.41s ( 37.02s elapsed)

Alloc rate 1,323,504,434 bytes per MUT second

Productivity 30.2% of total user, 38.7% of total elapsed

gc_alloc_block_sync: 7433188
whitehole_spin: 0
gen[0].sync: 0
gen[1].sync: 1017408

par1

我怎样才能更好地理解这里发生的事情?

最佳答案

你有一个很大的 RGBA 像素列表。为什么不使用 parListChunk具有合理的 block 大小?

关于haskell - 延迟 IO + 并行 : converting an image to grayscale,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24545148/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com