如何测量Haskell程序的顺序和并行运行时

时间:2011-07-08 10:41:31

标签: haskell runtime parallel-processing measurement

我正在测量此question中的haskell程序以生成带有运行时和加速总结的下表,以便我可以在图中绘图。

#Cores     Runtimes       Speedups
                     Absolute  Relative
Seq        ?         ..        ..
1          3.712     ..        ..
2          1.646     ..        ..

第一个问题

虽然通过编译带有-threaded标志的程序(下面的[3]和[4])来获取1和2核上的运行时,但我不确定顺序的那个时间( [1]或[2]以下):

  • 应该是没有-threaded标志或
  • 编译的时间
  • 通过标志打开但未指定任意数量的核心,即没有-Nx

编译时没有-threaded标记

        $ ghc --make -O2 test.hs
    [1] $ time ./test           ## number of core = 1
        102334155

        real    0m4.194s
        user    0m0.015s
        sys     0m0.046s

使用-threaded标记

进行编译
        $ ghc --make -O2 test.hs -threaded -rtsopts
    [2] $ time ./test           ## number of core = not sure?
        102334155

        real    0m3.547s
        user    0m0.000s
        sys     0m0.078s

    [3] $ time ./test +RTS -N1  ## number of core = 1
        102334155

        real    0m3.712s
        user    0m0.016s
        sys     0m0.046s

    [4] $ time ./test +RTS -N2  ## number of core = 2
        102334155

        real    0m1.646s
        user    0m0.016s
        sys     0m0.046s

第二个问题

从上面可以看出,我使用time命令来测量运行时。我正在接受“真正的”时间。但是如果我运行带有-sstderr标志的程序,我会得到更详细的信息:

    $ ghc --make -O2 test.hs -rtsopts
    $ ./test +RTS -sstderr 
    102334155
             862,804 bytes allocated in the heap
               2,432 bytes copied during GC
              26,204 bytes maximum residency (1 sample(s))
              19,716 bytes maximum slop
                   1 MB total memory in use (0 MB lost due to fragmentation)

      Generation 0:     1 collections,     0 parallel,  0.00s,  0.00s elapsed
      Generation 1:     1 collections,     0 parallel,  0.00s,  0.00s elapsed

      INIT  time    0.00s  (  0.00s elapsed)
      MUT   time    3.57s  (  3.62s elapsed)
      GC    time    0.00s  (  0.00s elapsed)
      EXIT  time    0.00s  (  0.00s elapsed)
      Total time    3.57s  (  3.62s elapsed)

      %GC time       0.0%  (0.0% elapsed)

      Alloc rate    241,517 bytes per MUT second

      Productivity 100.0% of total user, 98.6% of total elapsed

我相信-sstderr提供了一个更准确的时间我应该使用而不是time命令。我对么?另外,我应该使用哪个“总时间”(3.57s或3.62s)?

最后,在进行这样的测量时,任何一般建议/良好做法?我知道有一些软件包允许我们对我们的程序进行基准测试,但我主要对手动测量(或使用脚本为我这样做)感兴趣。

另外:运行时间是运行程序3次的中位数。

1 个答案:

答案 0 :(得分:4)

我会将-N1用于单核时间。我认为这也限制GC使用一个核心(我觉得这似乎适合基准测试?),但其他人可能知道更多。

至于你的第二个问题,Haskell中基准测试的答案几乎总是使用criterion。 Criterion将允许您对程序的一次运行进行计时,然后您可以将其包装在运行程序-N1-N2等的脚本中。取3次运行的中位数是可以的非常快速和粗略的指标,但如果你想依靠结果,那么你将需要更多的运行。 Criterion运行您的代码并执行适当的统计数据,为您提供合理的平均时间,以及置信区间和标准偏差(并尝试纠正您的机器的繁忙程度)。我知道你问过自己做的最佳实践,但Criterion已经体现了很多:使用时钟时间,基准测试很多,并且你意识到,不要仅仅采用简单的结果。

如果您想对整个事情进行基准测试,那么Criterion对您的程序只需要很少的更改。加上这个:

import Criterion.Main

main :: IO ()
main = defaultMain [bench "My program" oldMain]

其中oldMain是您以前的主要功能。