首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >懒惰IO +并行:将图像转换为灰度

懒惰IO +并行:将图像转换为灰度
EN

Stack Overflow用户
提问于 2014-07-03 04:48:13
回答 1查看 262关注 0票数 7

我试图将并行性添加到将.bmp转换为灰度.bmp的程序中。我看到并行代码的性能通常要差2-4倍。我正在调整parBuffer /块状尺寸,似乎仍然无法对其进行推理。寻找指引。

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

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

串行实现实际上是:

代码语言:javascript
复制
toGray :: [RGBA] -> [RGBA]
toGray x = map luma x

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

串行实现运行在~10s,~550 in /像素。线程显微镜看起来很干净:

为什么这么快?我想它有一些懒惰的ByteString (即使Codec.BMP使用严格的ByteString--这里有隐式转换吗?)和融合。

添加并行性

添加并行性的第一次尝试是通过parList。哦,天哪。程序使用~4-5GB内存和系统开始交换。

然后,我阅读了Simon的O‘’Reilly书中的“使用parBuffer并行化懒散流”一节,并尝试了大尺寸的parBuffer。这仍然没有产生理想的业绩。火花的大小非常小。

然后,我试图增加火花大小,方法是分块惰性列表,然后继续使用parBuffer进行并行处理:

代码语言:javascript
复制
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

但是,这仍然不能产生理想的性能:

代码语言:javascript
复制
  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

我怎么才能更好地解释这是怎么回事?

EN

回答 1

Stack Overflow用户

发布于 2014-07-03 07:01:38

您有一个RGBA像素的大列表。为什么不使用具有合理块大小的parListChunk呢?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24545148

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档