分析部分评估的程序

为了描述部分评估的程序,我有兴趣了解终止GHC程序的最佳方法。 对于需要花费很长时间才能运行的程序进行性能分析非常有用,可能只要永久性运行。

使用GHC 7.4.2,我可以通过启用分析(-prof -auto-all)和使用+RTS -p运行我的程序来分析非终止程序。 这生成了增量分析数据。 该程序可能会被^c杀死,并且.prof文件将包含数据。 在GHC 7.6和更高版本中,看起来如果程序可以用一个^ c结束,那么分析信息被写入输出。 但是(特别是对于更新版本的GHC?)单个^ c不会杀死程序,至少在我不耐烦之前再次击中^ c。 通常两个^ c会杀死程序,但是没有分析数据被写入输出。

具体来说,考虑试图分析StupidFib.hs的问题:

fib n = fib (n - 1) + fib (n - 2)
main = print $ fib 100

使用-prof编译并使用+ RTS -p运行,我可以在执行的第一个大约10秒内用单个^ c来终止该程序,但在此之后只有两个^ c将完成这项工作。 看着我的资源,这种改变似乎与使用我所有物理内存并转向交换空间的程序相吻合,但这可能是巧合。

为什么^ c有时可以工作,但是对于同一个程序,其他时间却不行? 当程序没有自行终止时,确保分析数据将被打印的最简单方法是什么?


最有可能的是,第二个信号在程序完成处理第一个信号之前已经交付,此时信号的动作已被重置为缺省动作,对于SIGINT来说,该动作将终止程序。 由于交换,在分析代码写出分析数据之前有一段很长的时间间隔,在此期间程序易受第二个信号情报。

故事的道德:要有耐心。 如果等待足够长时间,程序将结束,数据将被写出。 关于第二个^ C,告诉自己,“只是不要这样做!” :-)

有人可能会争辩说,Haskell运行时应该设置信号选项,以便第二个SIGINT被忽略,但这样做会带来风险,因为如果事情真的搞砸了,试图处理信号就没有简单的方法来终止程序。

您可能还希望避免程序超过物理内存并导致大量交换。 在那个时候,你的计算是有效的,并且没有太多的意义。 使用+RTS -M限制堆大小以避免陷入这种情况。

链接地址: http://www.djcxy.com/p/43415.html

上一篇: Profiling a partially evaluated program

下一篇: Learning to write a compiler