-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
process.hrtime() unreliable? #13102
Comments
FWIW, I had this test fail for me locally on OS X yesterday... |
That's probably it. |
Just because the units of measurement is nano-seconds doesn't mean that its precise to anything like that. I think it used to be still limited by the kernel tick, 1 or 10 milliseconds IIRC (I quite likely do not). @Trott are you running Linux in a VM? I recall @bnoordhuis saying that VMs were emulating the RDTSC instruction causing process.hrtime() to be slow and unreliable in VMs, any chance you are running into that? EDIT: Speak of the devil... hi Ben! |
@bnoordhuis The first
@sam-github The failure is from test-digitalocean-ubuntu1604-x86-1 in our CI infrastructure. I assume it's a virtual machine at Digital Ocean, but @jbergstroem or someone on @nodejs/build would be able to say with certainty. |
If it's both likely and acceptable that running in a Linux VM can result in a reported elapsed time of 0 in this situation, then at least I think I have a clear solution. We already have an "allow 0 operations" option for these tests in the benchmark |
@evanlucas I don't suppose you recall if it was a timeout or if it threw the error shown here or if t was something else, do you? I tried everything I could think of to get my macOS machine to trip this error and gave up. |
Ah no never mind it was a timeout. Sorry for the noise. |
Imprecision in process.hrtime() in some situations can result in a zero duration being used as a denominator in benchmark tests. This would almost certainly never happen in real benchmarks. It is only likely in very short benchmarks like the type we run in our test suite to just make sure that the benchmark code is runnable. So, if the environment variable that we use in tests to indicate "allow ludicrously short benchmarks" is set, convert a zero duration for a benchmark to 1 nano-second. Fixes: nodejs#13102
Imprecision in process.hrtime() in some situations can result in a zero duration being used as a denominator in benchmark tests. This would almost certainly never happen in real benchmarks. It is only likely in very short benchmarks like the type we run in our test suite to just make sure that the benchmark code is runnable. So, if the environment variable that we use in tests to indicate "allow ludicrously short benchmarks" is set, convert a zero duration for a benchmark to 1 nano-second. PR-URL: #13110 Fixes: #13102 Fixes: #12433 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Imprecision in process.hrtime() in some situations can result in a zero duration being used as a denominator in benchmark tests. This would almost certainly never happen in real benchmarks. It is only likely in very short benchmarks like the type we run in our test suite to just make sure that the benchmark code is runnable. So, if the environment variable that we use in tests to indicate "allow ludicrously short benchmarks" is set, convert a zero duration for a benchmark to 1 nano-second. PR-URL: #13110 Fixes: #13102 Fixes: #12433 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
From https://ci.nodejs.org/job/node-test-commit-linux/9926/nodes=ubuntu1604-32/consoleText:
Relevant code
Quick and easy
test/benchmark/check_is_http_token.js
: Pretty straightforward, but worth checking for anything funky.lib/_http_common.js
: The_checkIsHttpToken()
function is also straightforward, but worth looking at just in case...Slightly more involved
benchmark/common.js
:Benchmark.prototype.start()
andBenchmark.prototype.end()
are pretty straightforward and seem unlikely sources of the problem. Thethrow
in the stack trace above is on line 200 (currently). This is the "what in the world is going on?!?!?!" part.process.hrtime()
is called in one function and saved tothis._time
. Then at a later time,process.hrtime(this._time)
is called and the result is[0, 0]
. ???? (I don't see anything funky going on withthis
but maybe there's a subtlety I'm missing?)Deeper dive
lib/internal/process.js
:setup_hrtime()
src/node.cc
:Hrtime()
deps/uv/src/unix/linux-core.c
:uv__hrtime()
Anything at all going on in the above that could somehow result in this odd behavior?
Possible causes
I'm having trouble coming up with an explanation that seems likely, but it's gotta be something, so...
common.js
that causesthis._time
to be set incorrectly.Deeper dive
items listed above?clock_gettime()
too many times in fast succession might return the same time even though it's supposed to have nanosecond precision in this situation?)Any other ideas?
/cc @nodejs/benchmarking @mscdex @joyeecheung @jasnell @nodejs/build @addaleax @saghul
Refs: #12934
The text was updated successfully, but these errors were encountered: