【问题标题】:How to bechmark a method in Octave?如何在 Octave 中对方法进行基准测试?
【发布时间】:2021-01-18 23:32:37
【问题描述】:

Matlab 有timeit 方法,有助于比较一个实现与另一个实现的性能。我在八度音阶中找不到类似的东西。我编写了这个基准方法,运行函数 f N 次,然后返回所用的总时间。这是比较不同实现的合理方法还是我错过了“热身”之类的关键内容?

function elapsed_time_in_seconds = benchmark(f, N)
  % benchmark runs the function 'f' N times and returns the elapsed time in seconds.

  timeid = tic;
  for i=1:N
    output = f();
  end
  elapsed_time_in_seconds = toc(timeid);
end

【问题讨论】:

  • 您可能要考虑的另一件事是实时与 cputime。根据the octave manual:“如果您对进程使用的 CPU 时间更感兴趣,则应使用 cputime 函数。tic 和 toc 函数报告调用之间经过的实际挂钟时间。这可能包括时间花在处理其他工作或什么都不做。”

标签: performance matlab octave


【解决方案1】:

MATLAB 的timeit 执行以下操作(您可以阅读整个函数,它是一个 M 文件):

  1. 粗略估计t_rough调用函数f的时间。
  2. 使用估计值确定N,使得N*t_rough 约为0.001 秒。
  3. 确定M 使得M*N*t_rough 不超过15 秒,但M 必须介于3 和11 之间。
  4. 循环M次:
  5.    拨打f()N次并记录总时间。
  6. 确定M 次的中位数除以N

MN这两个循环的目的如下:调用f()Ntimes确保tic/toc测量的时间足够大是可靠的,这个循环避免了尝试对时间太短以至于无法计时的事情进行计时。重复测量M 次并保持中值尝试使测量对系统上发生的其他事情造成的延迟具有稳健性,这可能会人为地夸大记录的时间。

该函数通过其句柄减去调用函数的开销(通过对空函数的调用计时来实验确定),以及tic/toc 调用时间(也通过实验确定)。它并没有减去内循环的成本,大概是因为在 MATLAB 中它是由 JIT 优化的,它的成本可以忽略不计。

还有一些进一步的改进。确定t_rough 的函数首先通过两次调用tictoc,然后使用while 循环确保调用f() 至少0.001 秒。但是在这个循环中,如果第一次迭代至少需要 3 秒,那么它只是将那个时间作为粗略估计。如果第一次迭代耗时较少,则丢弃第一次计数(预热),然后使用所有后续调用的中位数作为时间的粗略估计。

使用正确数量的输出参数调用函数 f() 也付出了很多努力。

代码中有很多cmets解释了所有这些步骤背后的原因,值得一读。


至少,我会按如下方式扩充您的基准测试功能:

function elapsed_time_in_seconds = benchmark(f, N, M)
  % benchmark runs the function 'f' N*M times and returns the elapsed time in seconds.

  tic; [~] = toc; tic; [~] = toc; % warmup
  output = f(); % warmup

  t = zeros(M, 1);
  for k=1:M
    timeid = tic;
    for i=1:N
      output = f();
    end
    t(k) = toc(timeid) / N;
  end
  elapsed_time_in_seconds = median(t);
end

如果使用函数直接比较各种备选方案,保持NM不变,那么tictoc、函数调用和循环的开销就无关紧要了。

此函数确实假设f 有一个输出参数,但不一定如此。您可以只调用f() 而不是output = f(),它适用于有或没有输出参数的函数。但是,如果函数需要一定数量的输出才能正常工作,或者触发您想要计时的计算,那么您必须调整函数以使用正确数量的输出参数调用它。

您可以想出一些启发式方法来从N 中确定M,这样会更容易使用此函数。

【讨论】:

  • @Turbo:在 MATLAB 提示符下键入 edit timeit
  • @Turbo:它曾经在 FileExchange 上,但我猜一旦它被添加到核心 MATLAB 中,他们就会从那里拉出来。这是作者 Steve Eddins 讨论此功能的原始博客文章:blogs.mathworks.com/steve/2008/02/29/timing-code-in-matlab/… - 他还有几篇博客文章谈论升级。
  • 我可以通过在matlab online 运行edit timeit 来查看源代码。
  • @Tasos,在引入 JIT 之前,预热在 MATLAB 中很有用。 MATLAB 一直只读入和解析每个函数一次(直到clear all)。我认为 Octave 做同样的事情,因为它是有道理的。但我不知道。
  • @Tasos:确实,Octave 也是如此。例如运行tic; cos(2); toc 几次,从一个新的会话开始。第一次花费的时间大约是其他时间的 10 倍,尽管这三个都是内置方法。
猜你喜欢
  • 2011-02-02
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多