Prolog 中微基准测试的维度
Dimensions of micro-benchmarking in Prolog
我想对谓词进行微基准测试 int_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/), int_cntB0_cntB(I0,W1,W).
我不是 100% 确定我需要考虑什么才能获得好的结果...什么是有趣的维度?
到目前为止,我想到了:我应该将元调用性能纳入基准测试还是应该与原始数字运算有关?循环是否应该是故障驱动的?我是否应该关心执行过程中产生的垃圾?
以下代码片段是一个简单的基准测试实现,用于原始性能、故障驱动并且(因此)不关心垃圾:
:- 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的代码:
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).
在 Intel Core i7 Haswell 机器上 运行 由于不同的基准测试方法(A、B、C)导致的 SICStus Prolog 4.3.1 最坏情况下的性能差异超过 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
你有什么想法吗if/how 我可以进一步减少微基准测试的开销吗?谢谢!
冷暖要注意运行。现代序言
系统有及时索引甚至编译。以便
不同的 运行 可以有不同的行为。还有垃圾回收
使时间变化。
我总是测量温暖的 运行s,所以我让 运行 先做基准测试
至少一次,然后扔掉措施。然后我
运行 再做一次并记下测量值。
转换不同的循环。通常的方法是测量
通过在循环中插入一个虚拟谓词来减少循环开销,
并测量循环时间。然后再减去这次。
虚拟谓词可以很容易地定义为:
dummy.
如果你看到looping everhead很小,我觉得是
也适用于不进入减去循环的长度
架空并清楚地说明您的测量也测量
循环。
当您使用相同的循环时,您仍然可以比较
您的线束 运行 所在的不同测试对象的结果,
即使你不减法。
我想对谓词进行微基准测试 int_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/), int_cntB0_cntB(I0,W1,W).
我不是 100% 确定我需要考虑什么才能获得好的结果...什么是有趣的维度?
到目前为止,我想到了:我应该将元调用性能纳入基准测试还是应该与原始数字运算有关?循环是否应该是故障驱动的?我是否应该关心执行过程中产生的垃圾?
以下代码片段是一个简单的基准测试实现,用于原始性能、故障驱动并且(因此)不关心垃圾:
:- 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的代码:
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).
在 Intel Core i7 Haswell 机器上 运行 由于不同的基准测试方法(A、B、C)导致的 SICStus Prolog 4.3.1 最坏情况下的性能差异超过 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
你有什么想法吗if/how 我可以进一步减少微基准测试的开销吗?谢谢!
冷暖要注意运行。现代序言 系统有及时索引甚至编译。以便 不同的 运行 可以有不同的行为。还有垃圾回收 使时间变化。
我总是测量温暖的 运行s,所以我让 运行 先做基准测试 至少一次,然后扔掉措施。然后我 运行 再做一次并记下测量值。
转换不同的循环。通常的方法是测量 通过在循环中插入一个虚拟谓词来减少循环开销, 并测量循环时间。然后再减去这次。 虚拟谓词可以很容易地定义为:
dummy.
如果你看到looping everhead很小,我觉得是 也适用于不进入减去循环的长度 架空并清楚地说明您的测量也测量 循环。
当您使用相同的循环时,您仍然可以比较 您的线束 运行 所在的不同测试对象的结果, 即使你不减法。