如何衡量ECLiPSe CLP中方法的执行时间?目前,我有这个:
measure_traditional(Difficulty,Selection,Choice):-
statistics(runtime, _),
time(solve_traditional(Difficulty,Selection,Choice,_)),
time(solve_traditional(Difficulty,Selection,Choice,_)),
time(solve_traditional(Difficulty,Selection,Choice,_)),
time(solve_traditional(Difficulty,Selection,Choice,_)),
time(solve_traditional(Difficulty,Selection,Choice,_)),
time(solve_traditional(Difficulty,Selection,Choice,_)),
time(solve_traditional(Difficulty,Selection,Choice,_)),
time(solve_traditional(Difficulty,Selection,Choice,_)),
statistics(runtime,[_|T]), % T
write(T).
我需要编写执行方法 solve_traditional(...)所花费的时间,并将其写入文本文件。但是,它不够精确。有时 time 将为给定方法打印0.015或0.016秒,但通常打印0.0秒。
确定方法完成得太快,我决定使用 statistics(runtime,...)来测量两次运行时调用之间的时间。然后,我可以测量完成20次方法调用所需的时间,并将测量的时间T除以20。
唯一的问题是,20次调用T等于0,16,32或48毫秒。显然,它分别测量每个方法调用的时间,并找到执行时间的总和(通常只有0.0秒)。这超过了测量N方法调用的运行时间并将时间T除以N的全部目的。
简而言之:我用于执行时间测量的当前方法是不合适的。有没有办法使它更精确(例如9位小数)?
答案 0 :(得分:5)
基准测试在任何编程语言中都是一项棘手的业务,特别是在CLP中。特别是如果您计划发布结果,您应该非常彻底,并且绝对确定您正在衡量您声称要衡量的内容。
计时器:您是在测量实时,处理CPU时间,线程CPU时间吗?包括在系统调用中花费的时间?包括或不包括垃圾收集? ...
查看statistics/2原语提供的不同计时器。 有一个实时高分辨率计时器可以通过statistics(hr_time,T)访问。
计时器分辨率:在您的示例中,计时器分辨率似乎为1/60秒。这意味着,要在时间测量中获得3位有效数字,您必须至少测量1000 * 1/60 = 16.7秒的运行时间。
如果你的基准测试运行时太短,你必须多次运行它。
运行时差异:在现代机器上,获得可重现的计时越来越困难。这是因为与您正在测量的程序无关的效果,例如缓存行为,分页,上下文切换,电源管理硬件,内存对齐等。
运行足够的重复次数,在安静的机器上运行,确保结果可重复。
重复基准:在像ECLiPSe这样的系统中,必须小心地重复运行基准测试,以确保连续运行实际上执行相同的计算,并且理想情况下具有相同或类似的缓存和垃圾收集行为。
在您的代码中,您连续运行基准测试。建议不要这样做,因为变量实例化,延迟目标或垃圾可以从之前的运行中继续存在并减慢或加速后续运行。如上所述,您可以使用模式
run_n_times(N,Goal) :- \+ ( between(1,N,1,_), \+ Goal ).
本质上是一种重复N次序列的方法
once(Goal), fail
重点是once/1
和fail
的组合撤消了所有Goal
的计算,以便下一次迭代尽可能从a benchmark(N, DummyGoal, Goal, Time) :-
cputime(T1),
run_n_times(N, DummyGoal),
cputime(T2),
run_n_times(N, Goal),
cputime(T3),
Time is (T3-T2)-(T2-T1).
开始类似的机器状态。不幸的是,这个撤销过程本身增加了额外的运行时间,这会扭曲测量...
测试开销:如果您多次运行基准测试,则需要一个为您执行此操作的测试框架,这有助于您测量的运行时。
您必须确保开销可以忽略不计,或者您必须测量开销(例如,通过使用虚拟基准运行测试框架)并减去它,例如:
public function show($category_id, $title) {
$topic = Topic::where('category_id', $category_id)
->where('title', $title)
->firstOrFail();
return view('forums.category')
->with('topic', $topic);
}
CLP细节还有许多其他注意事项特定于CLP解算器中发生的数据驱动操作类型,这使得CLP运行时很难比较。这些求解器在传播器的调度,修剪程度,搜索控制中的打破规则等方面有许多内部自由度。
专门讨论这些事情的论文是: 基准测量约束逻辑编程平台,作者:Mark Wallace,Joachim Schimpf,Kish Shen和Warwick Harvey。在CONSTRAINTS Journal中,编辑。 E.C. Freuder,9(1),pp 5-34,Kluwer,2004 。