微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 Octave 中对方法进行基准测试?

如何解决如何在 Octave 中对方法进行基准测试?

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

解决方法

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() N 次确保 tic/ toc 足够大而可靠,此循环避免尝试对太短以至于无法计时的事物计时。重复测量 M 次并保持中位数尝试使测量稳健,以防止系统上发生的其他事情引起的延迟,这可能会人为地增加记录的时间。

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

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

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

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


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

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(),它适用于有或没有输出参数的函数。但是如果函数需要有一定数量的输出才能正常工作,或者触发你想要计时的计算,那么你必须调整函数以使用正确数量的输出参数调用它。

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。