2

如何测量 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(...)所花费的时间并将其写入文本文件。但是,它不够精确。对于给定的方法,有时时间会打印 0.015 或 0.016 秒,但通常会打印 0.0 秒。

考虑到方法完成太快,我决定使用统计信息(运行时,...)来测量两次运行时调用之间所花费的时间。例如,我可以测量完成 20 次方法调用所需的时间,并将测量的时间 T 除以 20。

唯一的问题是,对于 20 次调用,T 等于 0、16、32 或 48 毫秒。显然,它分别测量每个方法调用的时间并找到执行时间的总和(通常只有 0.0 秒)。这超出了测量 N 个方法调用的运行时间并将时间 T 除以 N 的全部目的。

简而言之:我用于执行时间测量的当前方法是不够的。有没有办法让它更精确(例如 9 位小数)?

4

1 回答 1

4

在任何编程语言中,基准测试都是一项棘手的工作,尤其是在 CLP 中。特别是如果您打算发布您的结果,您应该非常彻底,并绝对确保您正在测量您声称要测量的内容。

Timers:你是在测量实时、进程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/1fail撤消所有Goal的计算,以便下一次迭代尽可能从相似的机器状态开始。不幸的是,这个撤销过程本身增加了额外的运行时间,这会扭曲测量......

测试开销:如果您多次运行基准测试,您需要一个测试框架来为您完成这项工作,这有助于您测量的运行时。

您要么必须确保开销可以忽略不计,要么必须测量开销(例如,通过使用虚拟基准运行测试框架)并将其减去,例如:

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).

CLP 细节:对于发生在 CLP 求解器中的数据驱动操作类型,还有许多其他注意事项,这使得 CLP 运行时很难比较。这些求解器在传播器调度、修剪程度、搜索控制中的平局规则等方面具有许多内部自由度。

一篇专门讨论这些事情的论文是: 关于基准约束逻辑编程平台,作者是 Mark Wallace、Joachim Schimpf、Kish Shen 和 Warwick Harvey。在CONSTRAINTS Journal中,编辑。EC Freuder,9(1),第 5-34 页,Kluwer,2004 年

于 2016-03-16T02:44:16.333 回答