我正在尝试对可能需要几秒钟才能完成的(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
会以某种方式提供此类信息吗?
答案 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/1
和install_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
而不是/1
。如果我们不这样做,则时间设置为0并且警报将连续触发谓词。
现在,与我最初问题的“确定性”问题更相关,我只能说虽然我的stat_point
会在我的时间和(不太可能的)记忆测量中加入不确定性,但这种不确定性最终取决于statistics/2
谓词。由于CPU时间受此调用的影响, magus 建议的解决方案 - 使用“主要标准”样本来查找我的测量值的偏移量 - 可能是减少这种不确定性的一种方法。 p>
事实上,由于使用的内存和执行时间已经远远大于重复调用statistics/2
所产生的内存,因此我的测量精度“相对”很小。