首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Haskell线程堆溢出,尽管总内存使用量只有22Mb?

Haskell线程堆溢出,尽管总内存使用量只有22Mb?
EN

Stack Overflow用户
提问于 2015-07-27 04:13:53
回答 1查看 1.9K关注 0票数 114

我正在尝试并行化一个光线跟踪器。这意味着我有一个很长的小计算列表。vanilla程序在特定场景下运行,运行时间为67.98秒,总内存使用量为13MB,生产率为99.2%。

在我的第一次尝试中,我使用了缓冲区大小为50的并行策略parBuffer。我之所以选择parBuffer,是因为它遍历列表的速度和消耗的火花一样快,并且不会像parList那样强制使用列表的主干,因为列表非常长,这将占用大量内存。使用-N2时,它的运行时间为100.46秒,总内存使用量为14MB,生产率为97.8%。spark信息是:SPARKS: 480000 (476469 converted, 0 overflowed, 0 dud, 161 GC'd, 3370 fizzled)

大量冒泡的火花表明火花的粒度太小,所以接下来我尝试使用策略parListChunk,它将列表拆分成块,并为每个块创建一个火花。我用块大小的0.25 * imageWidth得到了最好的结果。该程序运行时间为93.43秒,总内存使用量为236MB,生产率为97.3%。spark信息是:SPARKS: 2400 (2400 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)。我认为更大的内存使用量是因为parListChunk强制使用了列表的主干。

然后,我尝试编写自己的策略,懒惰地将列表划分为块,然后将块传递给parBuffer并连接结果。

代码语言:javascript
复制
 concat $ withStrategy (parBuffer 40 rdeepseq) (chunksOf 100 (map colorPixel pixels))

运行时间为95.99秒,总内存使用量为22MB,生产效率为98.8%。这是成功的,因为所有的火花都被转换了,内存使用率要低得多,但是速度并没有提高。以下是事件日志配置文件的一部分图像。

正如您所看到的,线程由于堆溢出而被停止。我尝试添加+RTS -M1G,它会将默认堆大小一直增加到1 1Gb。结果没有改变。我读到Haskell主线程会在堆栈溢出时使用堆中的内存,所以我也尝试用+RTS -M1G -K1G增加默认堆栈的大小,但这也没有影响。

还有什么我可以试一试的吗?如果需要,我可以发布关于内存使用或事件日志的更详细的概要信息,我没有全部包括,因为它是大量的信息,我认为没有必要包括所有这些信息。

编辑:我读到了关于Haskell RTS multicore support的文章,它谈到每个核心都有一个HEC (Haskell执行上下文)。每个HEC都包含一个分配区(它是单个共享堆的一部分)。每当任何HEC的分配区域耗尽时,都必须执行垃圾收集。这似乎是一个控制它的RTS option,-A。我尝试过-A32M,但看不出有什么不同。

EDIT2:Here is a link to a github repo dedicated to this question。我已经在性能分析文件夹中包含了性能分析结果。

EDIT3:下面是相关的代码:

代码语言:javascript
复制
render :: [([(Float,Float)],[(Float,Float)])] -> World -> [Color]
render grids world = cs where 
  ps = [ (i,j) | j <- reverse [0..wImgHt world - 1] , i <- [0..wImgWd world - 1] ]
  cs = map (colorPixel world) (zip ps grids)
  --cs = withStrategy (parListChunk (round (wImgWd world)) rdeepseq) (map (colorPixel world) (zip ps grids))
  --cs = withStrategy (parBuffer 16 rdeepseq) (map (colorPixel world) (zip ps grids))
  --cs = concat $ withStrategy (parBuffer 40 rdeepseq) (chunksOf 100 (map (colorPixel world) (zip ps grids)))

网格是由colorPixel.The预先计算和使用的随机浮点数,colorPixel类型为:

代码语言:javascript
复制
 colorPixel :: World -> ((Float,Float),([(Float,Float)],[(Float,Float)])) -> Color
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31641464

复制
相关文章

相似问题

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