【问题标题】:Random slowdowns in node.js executionnode.js 执行中的随机减速
【发布时间】:2022-08-19 06:22:40
【问题描述】:

我有一个用 node.js 编写的优化算法,它使用 cpu 时间(用performance.now() 测量)作为启发式算法。

但是,我注意到有时一些琐碎的代码行会比平时花费更多。

于是我写了一个测试程序:

const timings = [];
while (true) {
  const start = performance.now();
  // can add any trivial line of code here, or just nothing
  const end = performance.now();
  const dur = end - start;
  if (dur > 1) {
    throw [
      \"dur > 1\",
      {
        start,
        end,
        dur,
        timings,
        avg: _.mean(timings),
        max: _.max(timings),
        min: _.min(timings),
        last: timings.slice(-10),
      },
    ];
  }
  timings.push(dur);
}

测量结果显示平均值为 0.00003 毫秒,峰值 > 1 毫秒(第二高的 < 1 毫秒,但数量级相同)。

我能想到的可能原因有:

  1. 平均时间不是执行代码的实际时间(一些编译器优化)
  2. performance.now 不知何故不准确
  3. cpu 调度相关 - 进程未正常运行但仍计入性能。现在
  4. 偶尔节点在幕后做一些额外的事情(GC等)
  5. 硬件/操作系统级别发生的事情 - 缓存/页面错误等

    这些是可能的原因,还是其他原因?

    无论原因是什么,有没有办法为算法使用更准确的测量?

    当前异常值导致算法行为不端,并且不知道如何解决此问题,最好的选择是使用移动平均成本作为启发式方法,但有其缺点。

    提前致谢!

    - - - - 编辑

    我很欣赏performance.now() 永远不会准确,但有点惊讶它可以跨越 3-4 个数量级(而不是 2 个数量级或理想情况下为 1 个数量级。)

    有人对performance.now() 的工作原理有任何想法/指针吗?因此可能是错误范围的主要贡献者?

    很高兴知道原因是否是由于 node/v8 无法控制的某些东西(硬件/操作系统级别)与它确实可以控制的某些东西(与节点错误/选项/gc 相关),所以在考虑使用替代启发式的其他权衡之前,我可以决定是否有办法减少错误范围。

  • 您不太可能准确测量一行微不足道的代码的时间。事实上,执行performance.now() 的开销可能比执行一行微不足道的代码的时间要高很多倍。
  • 1,3 和 5 也是所有可能性。您不能保证您的代码获得一个不会中断的专用 CPU 内核来服务系统中的其他线程。在我的 Windows 系统中,即使我的 nodejs 是唯一运行的“应用程序”,还有数百个其他线程专门用于各种操作系统服务,这些线程可能会或可能不会在我的 nodejs 应用程序运行时请求一些时间来运行并最终得到一些我的 nodejs 应用程序正在使用的 CPU 内核的时间片。
  • @jfriend00 有没有关于 performance.now() 工作原理的文档?它不会不包括不在节点线程上工作的 cpu 时间吗? (nodejs.org/api/perf_hooks.html#performancenow 根本没有解释太多)另外顺便说一句,我对测量单行代码的性能并不是很感兴趣——我只是推断这个例子来证明performance.now() 跨越 3-4根据自身的数量级,并希望找到一种解释,并希望能找到一种以某种方式减少测量误差的方法。

标签: node.js performance v8


【解决方案1】:

这些是可能的原因,还是其他原因?

是的,它们听起来都很可能。

有没有办法为算法使用更准确的测量?

不,亚毫秒时间测量通常不可靠,而且几乎不是一个好主意。 (无论计时 API 是否承诺微/纳秒精度或其他任何东西都无关紧要;很可能(1)它在实践中无法成立,并且(2)试图依赖它会产生比它解决的问题更多的问题。你我刚刚找到了一个例子。)

即使以毫秒为单位也充满危险。我曾经调查过一个令人惊讶的性能案例,结果发现在硬件和操作系统的特定组合上,在 16 毫秒的满载后 CPU 的时钟频率增加了三倍,这当然与看起来表现的代码无关奇怪。

【讨论】:

  • 谢谢。您对performance.now() 的工作方式有任何想法/指示吗?我很欣赏它可能不准确,但有点惊讶它可能跨越 3-4 个数量级。很高兴知道原因是否是由于 node/v8 无法控制的东西(硬件/操作系统级别)与它确实可以控制的东西(与节点错误/选项/gc 相关),所以我可以在考虑使用替代启发式的其他权衡之前,决定是否有办法减小误差范围。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
  • 2010-12-16
  • 2018-02-03
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多