Prolog中微观基准测试的维度

Prolog中微观基准测试的维度,prolog,benchmarking,microbenchmark,sicstus-prolog,Prolog,Benchmarking,Microbenchmark,Sicstus Prolog,我想微基准谓词int\u cntA/2 int_cntA(I,W) :- I >= 0, int_cntA0_cntA(I,0,W). int_cntA0_cntA(0,W0,W) :- !, W0 = W. int_cntA0_cntA(I,W0,W) :- I0 is I/\(I-1), W1 is W0+1, int_cntA0_cntA(I0,W1,W). 。。。针对谓词int_cntB/2: int_cntB(I,W) :- I >= 0, int_cntB0

我想微基准谓词int\u cntA/2

int_cntA(I,W) :- I >= 0, int_cntA0_cntA(I,0,W).

int_cntA0_cntA(0,W0,W) :- !, W0 = W.
int_cntA0_cntA(I,W0,W) :- I0 is I/\(I-1), W1 is W0+1,      int_cntA0_cntA(I0,W1,W).
。。。针对谓词int_cntB/2:

int_cntB(I,W) :- I >= 0, int_cntB0_cntB(I,0,W).

int_cntB0_cntB(0,W0,W) :- !, W0 = W.
int_cntB0_cntB(I,W0,W) :- I0 is I>>1,     W1 is W0+(I/\1), int_cntB0_cntB(I0,W1,W).
benchB_1(I,W,Rt) :- statistics(runtime,_),
                    ( repeat(100000000),      int_cntB(I,W), false ; true ),
                    statistics(runtime,[_,Rt]),
                    int_cntB(I,W).

benchB_2(I,W,Rt) :- statistics(runtime,_),
                    ( between(1,100000000,_), int_cntB(I,W), false ; true ),
                    statistics(runtime,[_,Rt]),
                    int_cntB(I,W).

benchB_3(I,W,Rt) :- statistics(runtime,_),
                    ( rep_100M,               int_cntB(I,W), false ; true ),
                    statistics(runtime,[_,Rt]),
                    int_cntB(I,W).
我不确定我需要考虑什么才能得到好的结果……什么是有趣的维度

到目前为止,我提出了:我应该将元调用性能纳入基准测试,还是应该考虑原始的数字运算?回路是否应该是故障驱动的?我是否应该关心执行期间生成的垃圾

以下代码段是一个简单的基准测试实现,它追求原始性能,是故障驱动的,因此不关心垃圾:

:- use_module(library(between)).

rep_10.
rep_10.
rep_10.
rep_10.
rep_10.
rep_10.
rep_10.
rep_10.
rep_10.
rep_10.

rep_100M :- rep_10, rep_10, rep_10, rep_10, rep_10, rep_10, rep_10, rep_10.
int_cntA/2的代码:

benchA_1(I,W,Rt) :- statistics(runtime,_),
                    ( repeat(100000000),      int_cntA(I,W), false ; true ),
                    statistics(runtime,[_,Rt]),
                    int_cntA(I,W).

benchA_2(I,W,Rt) :- statistics(runtime,_),
                    ( between(1,100000000,_), int_cntA(I,W), false ; true ),
                    statistics(runtime,[_,Rt]),
                    int_cntA(I,W).

benchA_3(I,W,Rt) :- statistics(runtime,_),
                    ( rep_100M,               int_cntA(I,W), false ; true ),
                    statistics(runtime,[_,Rt]),
                    int_cntA(I,W).
int_cntB/2的代码:

int_cntB(I,W) :- I >= 0, int_cntB0_cntB(I,0,W).

int_cntB0_cntB(0,W0,W) :- !, W0 = W.
int_cntB0_cntB(I,W0,W) :- I0 is I>>1,     W1 is W0+(I/\1), int_cntB0_cntB(I0,W1,W).
benchB_1(I,W,Rt) :- statistics(runtime,_),
                    ( repeat(100000000),      int_cntB(I,W), false ; true ),
                    statistics(runtime,[_,Rt]),
                    int_cntB(I,W).

benchB_2(I,W,Rt) :- statistics(runtime,_),
                    ( between(1,100000000,_), int_cntB(I,W), false ; true ),
                    statistics(runtime,[_,Rt]),
                    int_cntB(I,W).

benchB_3(I,W,Rt) :- statistics(runtime,_),
                    ( rep_100M,               int_cntB(I,W), false ; true ),
                    statistics(runtime,[_,Rt]),
                    int_cntB(I,W).
在运行SICStus Prolog 4.3.1的Intel Core i7 Haswell计算机上,由于不同的基准测试方法(A、B、C),最坏情况下的性能差异超过100%:

| ?- benchA_1(0,W,Rt).
W = 0,
Rt = 3140 ? 
yes
| ?- benchA_2(0,W,Rt).
W = 0,
Rt = 4130 ? 
yes
| ?- benchA_3(0,W,Rt).
W = 0,
Rt = 1960 ? 
yes

你有没有想法,如果/如何进一步降低微基准测试的开销?谢谢大家!

你必须小心冷跑和热跑。现代序言 系统具有即时索引甚至编译功能。以便 不同的跑步行为可能不同。还有垃圾收集 使定时发生变化

我总是测量热身跑步,所以我让我先运行基准测试 至少一次,然后扔掉这个措施。然后我 再次运行它并记录测量结果

汇聚不同的环。通常的方法是测量 通过在循环中插入虚拟谓词来降低循环开销, 测量循环时间。然后再减去这一次。 伪谓词可以很容易地定义为:

  dummy.
如果你看到循环的everhead很小,我想是的 也适用于不进入减去循环的长度 开销,并明确说明您的测量值也可以测量 循环

当您使用相同的循环时,仍然可以比较 线束运行的不同测试对象的结果, 即使你不减法。

你也需要一些抽象的标准,比如指令的数量等等。通过gdb和PAPI连接。任何混凝土微基准都是毫无用处的。在SWI中,O编译为is/2,但仍然在没有-O的情况下运行通常比IRL更快。除非你发现一些奇怪的异常,否则Rt可能是一个实数,但永远都不是实数。