代码之家  ›  专栏  ›  技术社区  ›  man tou

v8 Atomics.wait timeout为什么错误这么大?

  •  0
  • man tou  · 技术社区  · 6 年前

    v8 shell执行以下代码:

    var msleep = n => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, n);
    var t = Date.now();msleep(1000);Date.now() - t;
    

    输出:

    1005
    

    为什么会有几毫秒的错误?

    Here 是一个错误仅为0.1毫秒的生锈示例。

    1 回复  |  直到 6 年前
        1
  •  1
  •   jmrk    6 年前

    也许你的机器很忙?这就是为什么任何事情都要比预期的时间长的主要原因。

    请注意,您不仅要测量超时时间,还要测量函数调用、对象创建(可能触发短暂的GC活动)、消息循环泵送和对系统库的调用。

    后者尤其可以解释这一点:在某些操作系统上,默认的计时器分辨率粗于1毫秒,因此当请求的超时时间用完时,内核可能会等到下一个计时器滴答才通知进程。

    我不能复制你的观察结果。我看到的大多是1000个,有时是1001个,这几乎是我所期望的:

    d8> var msleep = n => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, n);
    d8> function measure() { var t = Date.now(); msleep(1000); return (Date.now() - t); }
    d8> for (var i = 0; i < 30; i++) print(measure());
    1000
    1000
    1001
    1000
    1000
    1000
    1000
    1001
    1000
    1000
    1000
    1000
    1001
    1000
    1000
    1000
    1000
    1001
    1000
    1000
    1000
    1000
    1000
    1000
    1000
    1000
    1000
    1001
    1000
    1000
    

    通常不建议依赖于超时的准确性。E、 g.如果你想制作一个不会漂移的秒表,那么就花一个开始时间,并与之进行比较,如下所示:

    var start_time;
    function start_stopwatch() {
      start_time = Date.now();
      window.setTimeout(update_display, 1000);
    }
    function update_display() {
      var current_time = Date.now();
      call_display_function(current_time - start_time);
      window.setTimeout(update_display, 1000);  // Could be 876 for all we care.
    }
    

    而不是:

    var elapsed;
    function start_stopwatch_DONT_DO_THIS() {
      elapsed = 0;
      window.setTimeout(update_display_DONT_DO_THIS, 1000);
    }
    function update_display_DONT_DO_THIS() {
      elapsed += 1000;  // This is going to be inaccurate!
      call_display_function(elapsed);
      window.setTimeout(update_display_DONT_DO_THIS, 1000);
    }