如何在SWI-Prolog中定期调用statistics / 2?

时间:2014-02-11 19:44:45

标签: prolog swi-prolog

我正在尝试对可能需要几秒钟才能完成的(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会以某种方式提供此类信息吗?

2 个答案:

答案 0 :(得分:2)

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

如果您所做的只是测量内存和CPU,并且测量根本不需要查询prolog的内部(听起来就是这种情况),那么最好在O.S.中进行。例如。在linux中使用带有sleep命令的循环的shell脚本。

它更可能是准确的,因为你没有O.S的干扰。以任何方式使用prolog - 或者作为prolog / os相互交互以获取cpu /内存统计信息的时间问题,或者通过实际影响cpu / memory prolog使用的stat point谓词,这可能会使结果着色。

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

答案 1 :(得分:2)

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

这是对谓词stat_mem/0stat_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而不是/1。如果我们不这样做,则时间设置为0并且警报将连续触发谓词。

现在,与我最初问题的“确定性”问题更相关,我只能说虽然我的stat_point会在我的时间和(不太可能的)记忆测量中加入不确定性,但这种不确定性最终取决于statistics/2谓词。由于CPU时间受此调用的影响, magus 建议的解决方案 - 使用“主要标准”样本来查找我的测量值的偏移量 - 可能是减少这种不确定性的一种方法。 p>

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