cro*_*eea 11 profiling haskell ghc
为了分析部分评估的程序,我有兴趣了解终止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
Run Code Online (Sandbox Code Playgroud)
使用-prof进行编译并使用+ RTS -p运行,我可以在执行的第一个大约10秒内使用单个 ^ c 终止此程序,但之后只有两个^ c将执行该作业.看看我的资源,这个变化似乎与使用我所有物理内存并转移到交换空间的程序一致,但这可能是巧合.
为什么^ c有时会工作,而不是同一个程序的其他时间?当程序没有自行终止时,确保分析数据打印的最简单方法是什么?
最有可能的是,第二个信号是在程序完成处理第一个信号之前传递的,此时信号的操作已重置为默认操作,(对于 SIGINT)是终止程序。由于交换,在分析代码可以写出分析数据之前需要一段很长的时间间隔,在此期间程序很容易受到第二个 SIGINT 的攻击。
这个故事的寓意是:要有耐心。如果等待足够长的时间,程序将完成并且数据将被写出。关于第二个 ^C,告诉自己,“不要这样做!” :-)
有人可能会争辩说,Haskell 运行时应该设置信号选项,以便忽略第二个 SIGINT,但这会有风险,因为如果处理信号的事情真的搞砸了,就没有简单的方法来终止程序。
您可能还希望避免超出物理内存并导致大量交换的程序。到那时,您的计算实际上已停止,并且没有太多继续下去的意义。用于+RTS -M限制堆大小以避免陷入这种情况。