我使用的制表功能进行了一些实验
b-prolog版本8.1,对我观察到的性能感到非常惊讶。

这是我使用的代码。它计算将一些正整数N缩减为I所需的Collatz步骤1的数量:

%:- table posInt_CollatzSteps/2.               % remove comment to enable tabling
posInt_CollatzSteps(I,N) :-
   (  I == 1
   -> N = 0                                                % base case
   ;  1 is I /\ 1
   -> I0 is I*3+1, posInt_CollatzSteps(I0,N0), N is N0+1   % odd
   ;  I0 is I>>1,  posInt_CollatzSteps(I0,N0), N is N0+1   % even
   ).

要确定从I0I的所有整数所需的最大缩减步骤数:
i0_i_maxSteps0_maxSteps(I0,I,M0,M) :-
   (  I0 > I
   -> M0 = M
   ;  posInt_CollatzSteps(I0,N0),
      I1 is I0+1,
      M1 is max(M0,N0),
      i0_i_maxSteps0_maxSteps(I1,I,M1,M)
   ).

当我在不带制表符和带制表符的情况下运行一些查询?- time(i0_i_maxSteps0_maxSteps(1,1000000,0,MaxSteps)).时,观察到以下运行时(以秒为单位):

不含制表符的
  • :6.784
  • 带有制表符的
  • :2.323, 19.78 ,3.089、3.084、3.081

  • 通过添加:- table posInt_CollatzSteps/2.,查询速度提高了2倍。不过,我还是很困惑:
  • 第2次运行比第1次慢5倍以上。
    显然,大多数时间都花在GC上。从第3次运行开始,制表变体又变快了。
  • 暖跑(第3,第4,...)明显比冷跑(第1)慢。

  • 我没想到这一点!将此与我在xsb 3.6.0版中观察到的运行时进行对比:

    不含制表符的
  • :14.287
  • 带有制表的
  • :1.829, 0.31 0.308 0.31 0.333

  • 我能做什么?是否有任何指令或标志可以帮助我获得BProlog更好的性能?我在Linux上使用BProlog版本8.1 64位版本。

    最佳答案

    正在检查Jekejeke Prolog跟踪的备忘。只是去
    到n = 100'000。对于B-Prolog,以下命令行可以正常工作
    在Windows上:

    bp -s 40000000
    

    据说这相当于160MB的堆栈/堆空间。我都得到
    上 table 和非上 table 的热跑比冷跑更好:



    Jekejeke的备忘code使用来自
    模块假设。与B-Prolog制表相反,尾随的备忘录将在每次调用时重新计算所有内容。您需要手动将其添加到您的代码中:



    因此,在Jekejeke中仍有提高速度的空间。
    关于您的B-Prolog问题:当内存太小时
    紧,这可能会不规则地给您带来额外的压力
    GC,可能会导致您观察到的行为。

    再见

    附注:这是Jekejeke Prolog备注代码。你需要
    安装Jekejeke Minlog以使模块hypo可用。最好的
    是要安装最新版本:
    :- thread_local posInt_CollatzStepsm/2.
    
    mposInt_CollatzSteps(I,N) :-
       (  I == 1
       -> N = 0                                                % base case
       ;  posInt_CollatzStepsm(I,N) %%% memo check
       -> true
       ;  1 is I /\ 1
       -> I0 is I*3+1, mposInt_CollatzSteps(I0,N0), N is N0+1,   % odd
          assumez(posInt_CollatzStepsm(I,N)) %%% memo add
       ;  I0 is I>>1,  mposInt_CollatzSteps(I0,N0), N is N0+1,   % even
          assumez(posInt_CollatzStepsm(I,N)) %%% memo add
       ).
    
    ?- time(mi0_i_maxSteps0_maxSteps(1, 100000, 0, R)).
    % Up 724 ms, GC 71 ms, Thread Cpu 640 ms (Current 06/20/19 09:43:24)
    R = 350
    
    ?- time(mi0_i_maxSteps0_maxSteps(1, 100000, 0, R)).
    % Up 573 ms, GC 69 ms, Thread Cpu 500 ms (Current 06/20/19 09:43:27)
    R = 350
    

    关于performance - BProlog 8.1中的制表性能不均匀,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30026151/

    10-13 00:01