3

我正在尝试对可能需要几秒钟才能完成的(SWI-)Prolog 程序进行基准测试。我想随着时间的推移保存 CPU 时间和内存统计数据,然后能够显示一种进化图。类似于系统监视器的东西,但仅与我的程序有关。

为此,我尝试使用alarm/4

stat_start(Id) :-
    alarm(0.25,stat_point,Id,[remove(false),install(true)]). % 250 milliseconds

stat_stop(Id) :-
    remove_alarm(Id).

stat_point :-
    stat_cpu, % calls statistics/2 and appends values to a CSV file
    stat_mem. % calls statistics/2 and appends values to a CSV file

我根本无法在每个stat_point. 时间从几毫秒到几秒不等,我对此无能为力。和改变alarm/4的时间没有任何区别。我还尝试了一个简单的查询,例如:

?- alarm(1, write('hello\n'), Id, [remove(false),install(true)]),
   repeat,
   fail.

它也不起作用。我只是得到一个“你好”。我认为一个解决方案可能是stat_point在我的代码中插入调用,但它看起来不太优雅,是吗?此外,这些点不会等间距。

是否有适当的方法以定时方式监视 Prolog 程序?会profile/1以某种方式提供这种信息吗?

4

2 回答 2

2

我得出的结论是,不能将警报配置为定期触发谓词,或者至少不能自动触发。尽管其中一个选项alarm/4remove(false),但必须调用uninstall_alarm/1andinstall_alarm/1才能重新启动计时器。不这样做并且不调用remove_alarm/1,将产生资源泄漏,这可能会以某种方式受到保护并最终可能会停止实际的计时器。

这将是使用定期调用谓词stat_mem/0和的正确方法stat_cpu/0

stat_start(Id,T) :-
    alarm(T,stat_point(Id,T),Id,[remove(false),install(true)]).

stat_point(Id,T) :-
    uninstall_alarm(Id),
    install_alarm(Id,T),
    stat_mem, 
    stat_cpu.

请注意,在这种情况下,install_alarm/2需要调用 to 而不是/1. 如果我们不这样做,则时间设置为 0,警报将连续触发谓词。

现在,与我最初的问题的“确定性”问题更相关,我只能说,尽管我stat_point在时间和(不太可能的)内存测量中插入了不确定性,但这种不确定性最终是由statistics/2谓词决定的。由于 CPU 时间受此调用影响,因此magus建议的解决方案——使用“主要标准”样本来找到我的测量值的偏移量——可能是减少这种不确定性的一种方法。

事实上,由于使用的内存和执行时间已经远远大于重复调用所产生的那些,statistics/2因此我的测量精度“相对”很小。

于 2014-02-15T13:22:28.977 回答
1

我没有具体的答案,但可能值得说明您正在使用哪个操作系统,因为它可能是操作系统是潜在问题的根源(Windows 有什么机会?)。

如果您所做的只是测量内存和 cpu,并且测量根本不需要询问 prolog 的内部(听起来是这样),那么最好在操作系统中完成,例如。在 linux 中使用带有 sleep 命令的循环的 shell 脚本。

它更有可能是准确的,因为您不会以任何方式干扰操作系统与 prolog - 要么是时序问题,因为 prolog/os 相互交互以获取 cpu/内存统计信息,要么通过你的统计点谓词实际上会影响 cpu/memory prolog 的使用,这可能会影响您的结果。

然后,您可以在没有 prolog/您的程序作为“控件”运行的情况下运行脚本,然后再次使用 prolog,并将差异视为 prolog/您的程序的影响。不是很科学/精确,但可能是一个前进的方向。

于 2014-02-13T11:10:20.287 回答