【问题标题】:Improving treap implementation改进trap实施
【发布时间】:2011-06-05 08:11:56
【问题描述】:

这是我实现的一种陷阱(隐式键和一些存储在节点中的附加信息):http://hpaste.org/42839/treap_with_implicit_keys

根据分析数据,GC 花费了该程序 80% 的时间。据我了解,这是由于每次“修改”节点时,都会重新创建根路径上的每个节点。

我可以在这里做些什么来提高性能还是我必须进入 ST monad 的领域?

【问题讨论】:

  • @adamax:这种行为(重新创建直到根的所有内容)在不可变结构中很常见,你读过 Chris Okasaki 的 Purely Functional Data Structures 吗? cs.cmu.edu/~rwh/theses/okasaki.pdf他为此写了几篇论文。
  • 也许你应该通过使用+RTS -s -RTS 运行你的程序来验证这一点,因为当我使用 7.0.1 快速运行它时,我看不到你所说的这 80%,我看到大约 16%在 GC 中花费的时间。
  • @ScottWest:我用 ghc -O2 -prof --make test.hs 编译它并用 ./test +RTS -s -RTS 运行,它说 %GC time 77.4% (77.4% elapsed ),总时间为 8.7 秒。但我的 ghc 版本是 6.12.1。只是出于兴趣,您系统的总时间是多少?
  • @adamax,我的结果和你差不多。使用 ghc-7.0.1 和 -O2,运行时间为 8.027 秒,生产率为 16.8%。如果我使用 -O2 -funfolding-use-threshold=256 编译,运行时间为 3.863 秒,生产率为 24.9%。我尝试了一些其他选项和内联的东西,但这是我迄今为止最好的。
  • 别忘了 GHC 的垃圾回收选项:stackoverflow.com/questions/3171922/…

标签: performance optimization data-structures haskell garbage-collection


【解决方案1】:

使用 GHC 7.0.3,我可以重现您的繁重 GC 行为:

  $ time ./A +RTS -s
  %GC time      92.9%  (92.9% elapsed)
  ./A +RTS -s  7.24s user 0.04s system 99% cpu 7.301 total

我花了 10 分钟看完了这个节目。这是我所做的,按顺序:

  • 设置 GHC 的 -H 标志,增加 GC 中的限制
  • 检查开箱
  • 改进内联
  • 调整第一代分配区域

导致 10 倍的加速和大约 45% 的 GC 时间。


按顺序,使用 GHC 的魔法-H 标志,我们可以大大减少运行时间:

  $ time ./A +RTS -s -H
  %GC time      74.3%  (75.3% elapsed)
  ./A +RTS -s -H  2.34s user 0.04s system 99% cpu 2.392 total

还不错!

Tree 节点上的 UNPACK 编译指示不会执行任何操作,因此请删除它们。

内联 update 减少了更多运行时间:

 ./A +RTS -s -H  1.84s user 0.04s system 99% cpu 1.883 total

就像内联height

 ./A +RTS -s -H  1.74s user 0.03s system 99% cpu 1.777 total

虽然它很快,但 GC 仍然占主导地位——毕竟我们正在测试分配。 我们可以做的一件事是增加第一代的大小:

 $ time ./A +RTS -s -A200M
 %GC time      45.1%  (40.5% elapsed)
 ./A +RTS -s -A200M  0.71s user 0.16s system 99% cpu 0.872 total

正如 JohnL 所建议的,增加展开阈值会有所帮助,

 ./A +RTS -s -A100M  0.74s user 0.09s system 99% cpu 0.826 total

这是什么,比我们开始的速度快 10 倍?还不错。


使用ghc-gc-tune,您可以将运行时间视为-A-H 的函数,

有趣的是,最佳运行时间使用非常大的-A 值,例如

$ time ./A +RTS -A500M   
./A +RTS -A500M  0.49s user 0.28s system 99% cpu 0.776s

【讨论】:

  • 哇,太不可思议了!我对 ghc 6.12.1 有类似的行为,最大的加速是通过内联 update 和设置第一代大小来实现的。一个问题,您是否忘记在 -H 中包含 size 选项?只是 -H 似乎没有任何作用,而 -H64m 则可以。
  • 使用 GHC 7,-H 增加了 GC 的所有限制
  • 更准确地说,-H 是一种“自动-A”,它增加了-A 设置但不增加整体内存使用。这是可能的,因为我们正在复制 GC,因此在主要 GC 之间有很多内存未使用。增加 -A 并不总是一个好主意 - 在某些程序中,由于缓存未命中率增加,它会使事情变得更糟。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
  • 1970-01-01
  • 2011-04-15
相关资源
最近更新 更多