-
Notifications
You must be signed in to change notification settings - Fork 17.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
time: use monotonic clock to measure elapsed time #12914
Comments
Do we have a monotonic clock source we can export? If not, why should this be in the standard library and not just an On 13 October 2015 at 12:42, Benoit Sigoure notifications@github.com
|
Why should this be in the standard library: because it's a pretty fundamental thing, especially in a language geared towards systems programming. I see a lot of people timing how long operations take using Come on, even Java has it. |
Got any concrete examples? |
Any concrete examples of ..? People using |
I suppose what I'm getting at is this: If there's a broad need for such a package, why isn't there one that people are already using? |
|
I think there are two things: A) A proper monotonic clock package (there are multiple 3rd party ones) B) Measuring elapsed time on systems where system time may leap to either direction B is simpler. Either ensure and document that
|
On what platforms is time.Now() not monotonic? For linux/amd64, time.Now is implemented by runtime·nanotime, which is calling clock_gettime (via VDSO) with CLOCK_MONOTONIC. I see similar calls being used on linux/arm, openbsd, freebsd, etc. Instead of a new interface, can we document time.Now as monotonic? |
@crawshaw time.Now is not monotonic on any platform that supports settimeofday. On amd64 GNU/Linux time.Now does not actually use CLOCK_MONOTONIC, it uses CLOCK_REALTIME. It's runtime.nanotime that uses CLOCK_MONOTONIC. |
Sorry, I somehow missed that you mentioned nanotime yourself. That's not what implements time.Now, though, that is implemented by time·now. |
Ah right, thanks. I got confused by |
time.Now() is monotonic on windows. We use undocumented way to fetch time, but it is monotonic as far as I know. @dvyukov to confirm. Alex |
On Mon, Oct 12, 2015 at 9:07 PM, Andrew Gerrand wrote:
Because people incorrectly assume that time only moves forward? It's an extremely common mistake that even at Google we were trying to hammer in people's head. When you see the large impact that things such as leap seconds have (including at Google), it's easy to see this is a well known problem but also a recurring problem. How is it that a language geared towards systems programming that comes with such a rich standard library offers no standard way of measuring time correctly? Look at gRPC, every single use of |
I expect that if you care that much about time you will run your system clocks correctly. On a well-run system, time does only move forward and at a constant (enough) pace.
I don't understand this comment. Leap seconds don't exist at Google. It is true that if you use time.Now to measure time during a leap smear then your measurements may be off by approximately 0.001%. But time will still be monotonic. |
How about programs that run on client machines? Or server software that you sells to clients? |
I don't think we return monotonic time from time.Now on windows. This would be a bug, because time.Now should return system time which can be changed by user. |
What Dmitry said. Alex |
On Fri, Oct 23, 2015 at 9:50 PM, Russ Cox wrote:
I was working just down the hall from where you were in B43 in 2008, when the leap second smearing scheme was devised, because everybody remembered all too well how all hell broke loose for the previous leap second. |
I'm not quite understanding, why the I can understand the arguments about clocks should never go backwards but the fact that Is it feasible and would it be acceptable to expose a |
This package fills in the gap of the Go standard library discussed in golang/go#12914. Change-Id: Icefcb17a11a7061be369318b50ca0cd55c53e7da
For those who need a solution to this problem, here's a way to expose Go's own |
Looks like the current code on master uses 1885-2157 as the range of wall times when monotonic time is present. |
OK, this is checked in for Go 1.9. I moved the internal epoch to 1885 (max year 2157) to avoid any possible problem with NTP-epoch-derived times. I also adjusted the design doc to reflect this change and some minor encoding changes. Thanks for the constructive conversation everyone. |
|
|
CL https://golang.org/cl/36334 mentions this issue. |
Refs #12914. Change-Id: Iadac4cbef70db6a95b47f86eaffcfc63bfdb8e90 Reviewed-on: https://go-review.googlesource.com/36334 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
I'm looking at some code which assumes that times truncated to the same time are equal. Simplified: func main() {
t1 := time.Now().Truncate(1 * time.Second)
t2 := time.Now().Truncate(1 * time.Second)
h1, m1, s1 := t1.Clock()
h2, m2, s2 := t2.Clock()
if h1 == h2 && m1 == m2 && s1 == s2 {
if !t1.Equal(t2) {
fmt.Printf("BUG: times truncated to the same second, but are not equal:\n%v\n%v\n", t1, t2)
}
}
} The actual code is mapping times to windows; it assumes that all times within a given window will truncate to the same time. This doesn't seem unreasonable. Should Truncate discard the monotonic time component? |
I've noticed that TestDo_rateLimit_noNetworkCall test fails on Go master with the following error: --- FAIL: TestDo_rateLimit_noNetworkCall (0.00s) github_test.go:549: rateLimitErr rate reset = 2017-02-25 01:49:01 +0000 UTC, want 2017-02-25 01:49:01 +0000 UTC m=+60.206993003 (Source: https://travis-ci.org/google/go-github/jobs/205180544.) This is due to changes in Go 1.9 to perform monotonic elapsed time measurements. See golang/go#12914 and https://golang.org/design/12914-monotonic for full details. Make the test pass by modifying time first, round after, and strip the monotonic clock reading by using AddDate(0, 0, 0). Doing that eliminates the unwanted additional monotonic precision from wanted time, making the expected time equality true.
This adds an API that we can use to compare values against bpf_ktime_get_ns() BPF helper for the timeouts. Looks like golang doesn't offer such an interface, so we need to add a cgo version right here. Probably also better to not rely on go internals should they once change their clock source internally, etc. Related: golang/go#12914 Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This adds an API that we can use to compare values against bpf_ktime_get_ns() BPF helper for the timeouts. Looks like golang doesn't offer such an interface, so we need to add a cgo version right here. Probably also better to not rely on go internals should they once change their clock source internally, etc. Related: golang/go#12914 Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Go's standard library doesn't provide any API to access a monotonic clock source, which means one can't reliably time how long an operation takes without copy-pasting or importing some low-level platform-dependent code such as the
clock
package at https://github.com/davecheney/junk.This API doesn't necessarily need to return a
time.Time
, just returning a number of nanoseconds as auint64
would be enough, kinda like Java'sSystem.nanoTime()
.The text was updated successfully, but these errors were encountered: