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

time: Sleep(1 * time.Nanosecond) pauses at least 1.9ms on Windows 10 or Windows 7 #29485

Open
destinysync opened this Issue Dec 31, 2018 · 16 comments

Comments

Projects
None yet
7 participants
@destinysync
Copy link

commented Dec 31, 2018

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

go version go1.11.4 windows/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\admin\AppData\Local\go-build
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\Users\admin\go
set GOPROXY=
set GORACE=
set GOROOT=C:\Go
set GOTMPDIR=
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\admin\AppData\Local\Temp\go-build968081038=/tmp/go-build -gno-record-gcc-switches

What did you do?

https://play.golang.org/p/zbe1kiCREc0

time.Sleep function works correctly on Go Playground and Ubuntu desktop 18.04, but when on Windows 10 or Windows 7, time.Sleep pauses at least 1.9ms

What did you expect to see?

1ns

What did you see instead?

1.9951ms

@40345839668

This comment has been minimized.

Copy link

commented Dec 31, 2018

18.09 Sürüm İşletim sistemi windows10 pro, İşlemci mimarisi İ5 4460 proocesor yapı 17763

@40345839668

This comment has been minimized.

Copy link

commented Dec 31, 2018

Durma sebebine gelince sanırım macun yerine 300 c. ısıya duyarlı silikon kullandım teksebebi bu olmalı.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Dec 31, 2018

@40345839668 Most people who use this issue tracker can not read Turkish. Please comment in English. Thanks.

@destinysync A sleep of one nanosecond is unlikely to work on any system. A sleep is always going to be limited by the clock frequency of the system.

@ianlancetaylor ianlancetaylor changed the title time.Sleep(1 * time.Nanosecond) pauses at least 1.9ms on Windows 10 or Windows 7 time: Sleep(1 * time.Nanosecond) pauses at least 1.9ms on Windows 10 or Windows 7 Dec 31, 2018

@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Dec 31, 2018

@destinysync

This comment has been minimized.

Copy link
Author

commented Jan 1, 2019

@ianlancetaylor , not only 1 * time.Nanosecond, any time.Sleep duration less than 1.9ms, e.g., 500 * time.Microsecond, 1 * time.Millisecond, pauses at least 1.9ms.

My computer's CPU is Intel i5 8250U, which has 4 cores, 8 threads, and a max turbo speed of 3.4 GHz, when I tested on the same hardware inside virtual machine with Ubuntu desktop 18.04 operating system , time: Sleep(1 * time.Nanosecond) only pauses 26.079µs, while outside the virtual machine on a Windows 10 system, time: Sleep(1 * time.Nanosecond) pauses 1.9951ms, so the root of the problem might not be hardware related.

the difference between 1.9951ms and 26.079µs does not seem huge on normal occasions, but I am trying to build a reliable protocol on top of UDP, due to 1.9951ms delay per datagram , transferring a file with a size of only 10Mb between a UDP client and a UDP server on the same machine takes more than 15 seconds, in comparison, TCP finishes the task within 0.5 seconds.

@alexbrainman

This comment has been minimized.

Copy link
Member

commented Jan 1, 2019

when on Windows 10 or Windows 7, time.Sleep pauses at least 1.9ms

This is what I see on my Windows computer too.

1ms sleep for time.Sleep(time.Nanosecond) sounds about right for current Windows time.Sleep implementation. If you have suggestion on how to improve the code, you are most welcome.

Alex

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Jan 1, 2019

I was imprecise in referring to the clock frequency. I didn't mean the frequency of the processor. I meant the frequency of the operating system: how often it does timer interrupts.

It's entirely possible that there is something to be fixed here. But time.Sleep(time.Nanosecond) is unlikely to ever work as you expect. You should use a different mechanism. For a nanosecond delay a busy wait is appropriate. In fact just fetching the current time will most likely take more than one nanosecond.

@networkimprov

This comment has been minimized.

Copy link

commented Jan 1, 2019

@destinysync what does this yield?

a := time.Now()
b := <-time.After(1*time.Nanosecond)
fmt.Println(b.Sub(a))
@destinysync

This comment has been minimized.

Copy link
Author

commented Jan 1, 2019

@networkimprov

	for i:=0; i< 10; i++ {
		a := time.Now()
		b := <-time.After(1*time.Nanosecond)
		fmt.Println(b.Sub(a))
	}

yields:

2.0014ms
1.9888ms
1.9951ms
1.9934ms
1.9945ms
1.9945ms
1.9951ms
1.9951ms
1.9945ms
1.9946ms
@davecheney

This comment has been minimized.

Copy link
Contributor

commented Jan 2, 2019

@destinysync time.Sleep is not specified to sleep for precisely the duration requested, it is specified to sleep for at least the duration requested. The delta between the minimum--the duration you requested--and the observed is implementation and operating system dependent. I don't think there is anything to be fixed here.

@networkimprov

This comment has been minimized.

Copy link

commented Jan 2, 2019

That shows a possible resolution of 100ns (0.0001ms). Go may be calling an obsolete Windows API which doesn't support that.

Windows 7 supports 100ns resolution timers:
https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-setwaitabletimerex

EDIT: Go uses SetWaitableTimer for the profiler.

Windows 2000 supports 100ns resolution sleep:
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-kedelayexecutionthread

EDIT: A thread does not resume when the above call's Interval has elapsed; it becomes eligible for execution.

@dominikh

This comment has been minimized.

Copy link
Member

commented Jan 2, 2019

Related: #8687

@networkimprov

This comment has been minimized.

Copy link

commented Jan 2, 2019

@destinysync I suggest revising this issue to cover time.After/NewTimer since its precision is probably more important than time.Sleep. And time.After/AfterFunc is the right tool for protocol pauses.

EDIT: Possibly related: #17696

@40345839668

This comment has been minimized.

Copy link

commented Jan 2, 2019

Auto clock implementation in Turkey 1 hour different works we have to set this summer because it does not have the application

@networkimprov

This comment has been minimized.

Copy link

commented Jan 4, 2019

@alexbrainman @destinysync I suggested changing this issue to be about time.After/NewTimer. If you prefer, I'll open a separate issue regarding resolution of time.NewTimer on Windows; please let me know!

@alexbrainman

This comment has been minimized.

Copy link
Member

commented Jan 5, 2019

I suggested changing this issue to be about time.After/NewTimer. If you prefer, I'll open a separate issue regarding resolution of time.NewTimer on Windows; please let me know!

I do not know how to fix this issue. Regardless of what description of this issue is.

Alex

@networkimprov

This comment has been minimized.

Copy link

commented Jan 8, 2019

@alexbrainman @aclements

SetWaitableTimer claims 100ns resolution; Go currently uses it in the profiler but not elsewhere (that I could find). Wouldn't that improve time.NewTimer/After over its current ~2ms resolution?

https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-setwaitabletimerex

EDIT: hardware background...
https://en.wikipedia.org/wiki/High_Precision_Event_Timer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.