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

Timer 如何在SWI Prolog中定期调用statistics/2?,timer,prolog,swi-prolog,periodic-task,Timer,Prolog,Swi Prolog,Periodic Task,我正在尝试对一个可能需要几秒钟才能完成的(SWI-)Prolog程序进行基准测试。我希望通过时间节省CPU时间和内存统计数据,以便能够显示某种进化图。类似于系统监视器的东西,但只是我的程序 为此,我尝试使用报警/4: stat_start(Id) :- alarm(0.25,stat_point,Id,[remove(false),install(true)]). % 250 milliseconds stat_stop(Id) :- remove_alarm(Id). st

我正在尝试对一个可能需要几秒钟才能完成的(SWI-)Prolog程序进行基准测试。我希望通过时间节省CPU时间和内存统计数据,以便能够显示某种进化图。类似于系统监视器的东西,但只是我的程序

为此,我尝试使用
报警/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
我根本无法在每个
统计点之间获得正确的时间。时间从毫秒到秒不等,我对此无能为力。更改
报警/4
的时间没有任何区别。我还尝试了一个简单的查询,如:

?- alarm(1, write('hello\n'), Id, [remove(false),install(true)]),
   repeat,
   fail.
而且它也不起作用。我只听到一声“你好”。我认为一个解决方案可能是在我的代码中插入对
stat\u point
的调用,但它看起来不太优雅,不是吗?此外,这些点的间距也不相等


有没有一种合适的方法来定时监控Prolog程序?
profile/1
会以某种方式提供此类信息吗?

我没有一个具体的答案,但可能值得说明您使用的是哪种操作系统,因为可能是操作系统,这是潜在问题的根源(可能是windows)

如果您所做的只是测量内存和cpu,而测量根本不需要询问prolog的内部(听起来是这样),那么最好在O.s.中完成,例如在linux中,使用shell脚本,使用循环和sleep命令

这更可能是准确的,因为您不会以任何方式受到O.s.与prolog的干扰-prolog/os相互交互以获取cpu/内存统计信息时的计时问题,或者通过stat point谓词实际影响cpu/内存prolog使用,这可能会影响您的结果


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

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

这是使用定期调用谓词
stat\u mem/0
stat\u 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\u alarm/2
,而不是
/1
。如果我们不这样做,则时间设置为0,并且警报将连续触发谓词

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


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

我要说的是,在警报的情况下,你的测量结果会有很多不确定性。很难说您实际上应该做什么,但是最好测量一些定义良好的部分——我在Linux上!感谢您的帮助,我目前正在寻找如何在Prolog之外准确地测量过程统计信息。至少从20年9月起,在macOS上,SWI Prolog似乎已经消除了与此相关的任何错误,因为它在没有补充的
unistall\u报警(…),install\u报警(…)
块的情况下,对我来说工作可靠。