ghc运行时如何支持性能分析实现的?

10

我在注释中没有找到太多文档。 有没有关于这个的好博客文章或类似的东西?


2
经过一番相对无果的谷歌搜索,我恐怕 GHC 总部正忙于实现和改进它,无暇撰写博客。 - Daniel Fischer
3
我认为大部分情况仍然与Sansom&Jones论文描述的相似。你有什么特别感兴趣的吗? - Peter Wortmann
谢谢提供参考!那应该可以作为一个答案。我想rwh提到一些优化和剖析是不兼容的。 - user239558
2个回答

7
最好的关于性能分析框架的信息来源可能仍然是Patrick Sansom和Simon Peyton Jones的原始论文。可以在Sansom的博士论文以及稍后的论文中找到其他细节,其中包括正式规范。Simon Marlow还在Haskell Implementors' Workshop 2011的GHC状态更新中谈到了一些最近的变化。
成本中心分析背后的思想是使用“成本中心”节点注释表达式树,因此例如使用-auto-all,程序将具有以下注释:
fib n = {-# SCC foo #-} (case n of
                           0 -> 0
                           1 -> 1
                           n -> fib (n-1) + fib (n-2))

在运行时输入 fib 时,程序会查看当前的 "成本中心堆栈",并将 "foo" 添加到顶部。一旦评估退出 SCC 注释的范围,这将被反转。一些魔法确保如果,例如,n 恰好是一个惰性值,并且程序需要执行其代码,则必要时恢复适用于 代码的成本中心。

然后,此基础设施用于时间和空间分析:

  1. 定时器会定期检查成本中心堆栈。每次找到某个成本中心堆栈时,这就算作一个 "tick"。最终,运行时系统将从其 tick 数计数估算每个成本中心堆栈的时间,从而提供时间分析。

  2. 每当分配对象时,程序都会保存指向那个时间点的成本中心堆栈的指针。这使得垃圾收集器能够提供一个按分配位置分解的驻留字节数统计信息。

作为评论中要求的,关于优化的几句话:由于明显的原因,框架不能允许将非常量成本从一个成本中心移动到另一个成本中心的优化,这迫使优化器有时相当悲观。例如,在上面的示例中,当前版本的 GHC 将无法取消盒子的返回值,这意味着每个递归调用都会进行不必要的堆分配。
作为经验法则,人们不应该指望任何代码转换发生在 SCC 注释之间。如果有疑问,最好在调用堆栈中注释一个足够高的函数,这样性能关键的部分根本不会被注释。

0

根据您的需求,您可能会发现Jones、Marlow和Singh的这篇论文很有用。它包括在并行上下文中对GHC程序进行分析的实践,并包含一些您可能会发现有用的案例研究。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接