分析部分评估的程序 [英] Profiling a partially evaluated program

查看:74
本文介绍了分析部分评估的程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了剖析部分评估过的程序,我有兴趣了解终止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运行,我可以用单个 ^ c在执行的第一个约10秒内完成,但之后只有两个^ c会完成这项工作。看看我的资源,这种改变似乎与使用我所有物理内存并转移到交换空间的程序相吻合,但这可能是巧合。



为什么^ c有时会工作,但不是其他时间的同一个程序?什么是最简单的方法来确保在程序没有自行终止时打印分析数据?解析方案

最可能的,第二个信号在程序完成处理第一个信号之前被传送,此时信号的动作已被重置为缺省动作,对于SIGINT来说,该动作将终止程序。由于交换,在分析代码写出分析数据之前有一段很长的时间间隔,在这段时间内程序容易受到第二个SIGINT的攻击。<​​/ p>

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

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



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


For the purposes of profiling a partially evaluated program, I'm interested in knowing the best way to terminate a GHC program. This is useful for profiling programs that take a long time to run, possibly as long as forever.

With GHC 7.4.2, I was able to profile a non-terminating program by enabling profiling (-prof -auto-all) and running my program with +RTS -p. This generated incremental profiling data. The program could be killed with ^c, and the .prof file would contain data. In GHC 7.6 and later, it appears that if the program can be terminated with a single ^c, then profiling information is written to output. However (especially with newer versions of GHC?) a single ^c doesn't kill the program, at least not before I get impatient and hit ^c again. Usually two ^c will kill the program, but then no profiling data is written to output.

Concretely, consider the problem of trying to profile StupidFib.hs:

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

Compiling with -prof and running with +RTS -p, I can kill this program with a single ^c in the first approximately 10 seconds of execution, but after that only two ^c will do the job. Looking at my resources, this change appears to coincide with the program using all of my physical memory and moving to swap space, however that could be coincidental.

Why does ^c work sometimes, but not other times for the same program? What is the easiest way to ensure that profiling data will get printed when the program does not terminate on its own?

解决方案

Most likely, the second signal is being delivered before the program has finished handling the first one, and at this point the signal's action has been reset to the default action, which (for SIGINT) is to terminate the program. Because of the swapping, there's a significant interval before the profiling code can write out the profiling data, during which time the program is vulnerable to a second SIGINT.

Moral of the story: be patient. If you wait long enough, the program will finish and the data will be written out. Regarding that second ^C, tell yourself, "Just don't do it!" :-)

One could argue that the Haskell runtime should set signal options such that a second SIGINT is ignored, but that would be risky because there'd be no easy way to terminate the program if things got really messed up trying to handle the signal.

You probably also want to avoid programs that exceed physical memory and induce a lot of swapping. At that point, your computation is effectively stalled and there's not much point in continuing. Use +RTS -M to limit the heap size to avoid getting into this situation.

这篇关于分析部分评估的程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆