Skip to content
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

runtime: time.Now clock resolution unexpectedly low on Windows XP. #11313

Closed
dmitshur opened this issue Jun 21, 2015 · 5 comments
Closed

runtime: time.Now clock resolution unexpectedly low on Windows XP. #11313

dmitshur opened this issue Jun 21, 2015 · 5 comments

Comments

@dmitshur
Copy link
Contributor

What version of Go are you using (go version)?

go version go1.4.2 windows/386

What operating system and processor architecture are you using?

(I don't use this operating system normally, it was done on a one off instance for testing and that's when I made this discovery.)

OS Name:    Microsoft Windows XP Professional
OS Version: 5.1.2600 Service Pack 3 Build 2600

The Go website lists Windows XP or higher under the system requirements, so as I understand this platform is supported despite being outdated.

What did you do?

// Play with finding minimal time difference via subsequent calls to time.Now().
package main

import (
    "fmt"
    "time"
)

func timediff() time.Duration {
    t0 := time.Now()
    for {
        t := time.Now()
        if t != t0 {
            return t.Sub(t0)
        }
    }
}

func main() {
    var ds []time.Duration
    for i := 0; i < 10; i++ {
        ds = append(ds, timediff())
    }
    fmt.Printf("%v\n", ds)
}

What did you expect to see?

A one millisecond clock resolution.

[1.000ms 1.000ms 1.000ms 1.000ms 1.000ms 1.000ms 1.000ms 1.000ms 1.000ms 1.000ms]

What did you see instead?

A resolution as low as 15.6 milliseconds.

[15.625ms 15.625ms 15.625ms 15.625ms 15.625ms 15.625ms 15.625ms 15.625ms 15.625ms 15.625ms]

I very unsure if this is a bug or working as expected (I tried asking here). Please close if this is working as expected.

I do suspect it might be a bug, because of the following reason. It is related to findings in #8687.

Specifically, I notice that the Go runtime sets timeBeginPeriod(1) at startup, and I can confirm via ClockRes.exe that it works:

Maximum timer interval: 15.600 ms
Minimum timer interval: 1.000 ms
Current timer interval: 1.000 ms

(When the Go program isn't running, current timer interval is 15.600 ms.)

Despite the timer interval being set to 1.000 ms when Go programs run, it seems the time.Now() clock resolution on Windows XP (but not newer versions of Windows from what I know, I could not verify this) is still as low as 15.6 ms instead of 1.0 ms. Is that an unintended bug, or is it normal expected behavior on this platform?

@dmitshur dmitshur changed the title runtime: time.Now clock resolution unexpectedly high on Windows XP. runtime: time.Now clock resolution unexpectedly low on Windows XP. Jun 21, 2015
@ianlancetaylor ianlancetaylor added this to the Go1.6 milestone Jun 21, 2015
@alexbrainman
Copy link
Member

As far as I know, the way we extract time, 15.6 milliseconds timer resolution is as good as you're going to get on Windows XP. Let us know if you have a better way to do it.

Despite the timer interval being set to 1.000 ms when Go programs run ...

I don't see where / who sets timer interval to 1ms. Why do you say that?

Alex

@dmitshur
Copy link
Contributor Author

I don't see where / who sets timer interval to 1ms. Why do you say that?

I believe it's at https://github.com/golang/go/blob/go1.4.2/src/runtime/os_windows.c#L135 in 1.4.2, and here in latest master commit.

To quote you from Sep 9, 2014:

The problem is that we call timeBeginPeriod Windows API. It was introduced as part of
pprof implementation

changeset: 9786:9c5c0cbadb4d
user: Hector Chu [email protected]
date: Sat Sep 17 17:57:59 2011 +1000
summary: runtime: implement pprof support for windows

but I view it as "windows timer precision is very very low (about 15ms) comparing to other OSes, so lets get best precision whenever we can (1ms)".

It's also visible by running ClockRes.exe when a Go program is and is not running.

@dmitshur
Copy link
Contributor Author

As far as I know, the way we extract time, 15.6 milliseconds timer resolution is as good as you're going to get on Windows XP.

If that's true, that's good enough for me and this issue can stay closed. I've only opened it in case it was an unintended bug.

@alexbrainman
Copy link
Member

Fair enough. I was not sure where 1ms did come. Because no Microsoft documentation mention time.

Alex

@golang golang locked and limited conversation to collaborators Jun 25, 2016
@dmitshur
Copy link
Contributor Author

dmitshur commented Mar 17, 2018

I wanted to post a followup update on this issue, for posterity.

This issue was originally closed without being resolved, because:

the way we extract time, 15.6 milliseconds timer resolution is as good as you're going to get on Windows XP. Let us know if you have a better way to do it.

However, it seems it was actually resolved somewhere between Go 1.7 and 1.10. I recently tried the test program (posted in original issue report) on a toy machine with Windows XP (same one used to file the original issue), and here are results I got with Go 1.7 beta 2:

$ go version
go version go1.7beta2 windows/386

$ go run std_time.go
[15.625ms 15.625ms 15.625ms 15.625ms 15.625ms 15.625ms 15.625ms 15.625ms 15.625ms 15.625ms]

After updating to Go 1.10 (the last version to support Windows XP):

$ go version
go version go1.10 windows/386

$ go run std_time.go
[976.5µs 976.6µs 976.5µs 976.6µs 976.6µs 976.5µs 976.6µs 976.6µs 976.5µs 976.6µs]

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants