밀도가 높은 비트 벡터 —을 나타내는 데 임의 정밀도 정수를 사용하고 있습니다. 에서부터 수천에 이르기까지입니다.프롤로그 : 비트가 설정되어 있는지 테스트
내 코드가 자주 특정 비트가 약간의 변화 속도가 매우 빠르고 다른 사람보다한다면, 그래서 내가 볼 수있는 몇 마이크로 벤치 마크를 한 설정 (또는)됩니다 있는지 확인해야:
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 위의 변형은 모두 (거의) 똑같이 빠릅니다.
는 그럼 다음 interesting part of the SWI-Prolog manual 우연히 :가
getbit(+IntExprV, +IntExprI)
IntExprV
의IntExprI
번째 비트의 비트 값 (또는0
1
)로 평가. 두 인수 모두 음수가 아닌 정수로 평가되어야합니다. 결과는(IntExprV >> IntExprI)/\1
과 동일하지만, 시프트 된 값의 구체화가 방지되므로 더 효율적입니다.향후 버전에서는
getbit/2
으로 전화하여(IntExprV >> IntExprI)/\1
을 최적화하여 이식성과 성능을 모두 제공합니다.run(runtime, 10000000, 1<<1000-1, 200)
와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.
나는이 런타임 관찰 :
| SWI | SWI -O | SICStus | SICStus | | 7.3.23 | 7.3.23 | 4.3.2 | 4.3.3 | --------+-----------------+-------------------| bench_1 | 4547 ms | 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. |을bench_6(0, _, _) :- !. bench_6(N, V, P) :- getbit(V,P) =:= 1, N0 is N-1, bench_6(N0, V, P).내가 마이크로 benchmarkng에 대한 다음 코드를 사용 :
그래서 나는 getbit/2
을 체크 아웃
getbit/2
는 SWI - 프롤로그에게 500 %의 속도 향상을 준 :것으로 보인다.command-line option
-O
은 SWI-Prolog에 놀라운 속도 향상을 제공했습니다.
SICStus와 비슷한 속도 향상을 얻으려면 더 좋은 공식 (arith. fun. 등)이 있습니까?
미리 감사드립니다.
SWI-Prolog ['mpz_tstbit' 사용] (https : // github .com/SWI-Prolog/swipl-devel/blob/198feb84f2218c90f1d7d98eca6f1fe60375e3ff/src/pl-arith.C# L2680)에서 [GMP] (https://gmplib.org/manual/Integer-Logic-and-Bit-Fiddling. html) (하단을보세요). SICStus가 다중 정밀도 정수를 구현하는 방법을 알고 있습니까? –
@ 보리스. GMP를 알고 있지만 SWI가 어떻게 통합되는지 모르겠습니다. (저는 SWI 소스에서 여전히 길을 잃었습니다.) 링크를 가져 주셔서 감사합니다! SICStus에 관해서 : 나는 그것을 모른다. 그러나 나는 [tag : ffi]가 상당한 호출 오버 헤드를 초래한다는 직감을 가지고있다. 그러나 나는 확신 할 수 없다. 나는 그것을 확인하기 위해 C 인터페이스를 시도 할 것이다. – repeat
SWI는 너무 큰 정수에는 GMP를 사용합니다. src/*. c에서 getbit를 grep하면 링크 된 코드 행을 찾을 수 있습니다. –