rep*_*eat 4 benchmarking prolog microbenchmark sicstus-prolog
我使用任意精度整数来表示密集的位向量 - 大小从十几到几千不等.
我的代码经常需要检查是否设置了某些位,所以我做了一些微基准测试,看看某些变化是否明显快于其他变量:
bench_1(0, _, _) :- !. bench_1(N, V, P) :- V /\ (1 << P) =\= 0, N0 is N-1, bench_1(N0, V, P). bench_2(0, _, _) :- !. bench_2(N, V, P) :- (V >> P) /\ 1 =:= 1, N0 is N-1, bench_2(N0, V, P). bench_3(0, _, _) :- !. bench_3(N, V, P) :- (V >> P) /\ 1 =\= 0, N0 is N-1, bench_3(N0, V, P). bench_4(0, _, _) :- !. bench_4(N, V, P) :- (V >> P) /\ 1 > 0, N0 is N-1, bench_4(N0, V, P). bench_5(0, _, _) :- !. bench_5(N, V, P) :- 1 is (V >> P) /\ 1, N0 is N-1, bench_5(N0, V, P).
通过SWI和SICStus,上述变体都(几乎)同样快速.
然后我偶然发现了SWI-Prolog手册中的以下有趣部分:
getbit(+IntExprV, +IntExprI)计算第_ 位的位值(
0或1).两个参数都必须求值为非负整数.结果相当于但更有效,因为避免了移位值的实现.IntExprIIntExprV(IntExprV >> IntExprI)/\1未来版本将优化
(IntExprV >> IntExprI)/\1调用getbit/2,提供可移植性和性能.
所以我查了一下getbit/2:
bench_6(0, _, _) :- !. bench_6(N, V, P) :- getbit(V,P) =:= 1, N0 is N-1, bench_6(N0, V, P).
我使用以下代码进行微基准测试:
call_indi_delta(G, What, Delta) :-
statistics(What, [V0|_]),
call(G),
statistics(What, [V1|_]),
Delta is V1 - V0.
run(Ind, Reps, Expr, Pos) :-
Position is Pos,
Value is Expr,
member(P_3, [bench_1,bench_2,bench_3,bench_4,bench_5,bench_6]),
G =.. [P_3,Reps,Value,Position],
call_indi_delta(G, Ind, T_ms),
write(P_3:Reps=T_ms), nl,
false.
Run Code Online (Sandbox Code Playgroud)
随着run(runtime, 10000000, 1<<1000-1, 200)我观察到的这些运行时:
| SWI | SWI -O | SICStus | SICStus |
| 7.3.23 | 7.3.23 | 4.3.2 | 4.3.3 |
--------+-----------------+-------------------|
bench_1 | 4547ms | 3704ms | 900ms | 780ms |
bench_2 | 4562ms | 3619ms | 970ms | 850ms |
bench_3 | 4541ms | 3603ms | 970ms | 870ms |
bench_4 | 4541ms | 3633ms | 940ms | 890ms |
bench_5 | 4502ms | 3632ms | 950ms | 840ms |
--------+-----------------+-------------------|
bench_6 | 1424ms | 797ms | n.a. | n.a. |
看起来:
getbit/2给SWI-Prolog 加速了500%.
该命令行选项-O给SWI-Prolog的一个显着加速.
是否有更好的配方(arith.fun.等)与SICStus获得类似的加速?
先感谢您!
不,我认为配方比你尝试的配方更快.特别是,getbit/2在SICStus中没有任何东西(在编译算术时甚至没有在内部使用).
PS.walltime一般来说,我会使用基准测试.目前的操作系统不提供非常可靠的runtime.
PPS.我会添加一个使用测试代码序列的虚拟版本的基准测试,只是为了确保测试代码实际上比基准测试工具花费更多.(我做了,用一个dummy/3没有做任何事情的调用替换了bit-test ,使得速度更快.所以基准测试似乎没问题.)
| 归档时间: |
|
| 查看次数: |
80 次 |
| 最近记录: |