You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
$ GODEBUG='gctrace=1' go test -bench=BenchmarkGoTrace -benchtime=1000x -run=NONE -trace=trace.out
cpu: Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
BenchmarkGoTrace-8 1000 22500692 ns/op
gc 2259 @26.566s 5%: 0.24+3.9+0.44 ms clock, 1.9+0.35/1.3/0+3.5 ms cpu, 128->156->47 MB, 145 MB goal, 0 MB stacks, 0 MB globals, 8 P
gc 2260 @26.574s 5%: 0.21+8.1+0.088 ms clock, 1.6+4.3/6.7/0+0.71 ms cpu, 85->100->85 MB, 95 MB goal, 0 MB stacks, 0 MB globals, 8 P
gc 2261 @26.595s 5%: 0.19+2.5+0.094 ms clock, 1.5+0.032/0.85/0+0.75 ms cpu, 149->163->47 MB, 171 MB goal, 0 MB stacks, 0 MB globals, 8 P
$ go tool trace trace.out
What did you expect to see?
The actual pause time of goroutine due to GC.
What did you see instead?
The GC pause time is extremely large and does not match the time output by GODEBUG='gctrace=1'.
"GC pasue" uses the GCTime field, which corresponds to the GCDone event. It seems that this is the total GC time, and it is calculated for each goroutine.
I agree that the title of "GC pause" doesn't entirely match the calculation for that column.
The commit message of 61f92ee, when the calculation was last edited (during the Go 1.11 cycle), says "Goroutine analysis reports the sum of all overlapping GC intervals as the GCTime of a goroutine."
It looks like the calculation would make sense when running with a STW / non-concurrent garbage collector — but both the execution tracer and the concurrent GC were introduced in Go 1.5.
case EvGCSweepStart:
g := gs[ev.G]
if g != nil {
// Sweep can happen during GC on system goroutine.
g.blockSweepTime = ev.Ts
}
case EvGCSweepDone:
g := gs[ev.G]
if g != nil && g.blockSweepTime != 0 {
g.SweepTime += ev.Ts - g.blockSweepTime
g.blockSweepTime = 0
}
Maybe the calculation for the "GC pause" column should instead be the sum of the GC-related STW pauses, plus any time in GCAssist? Plus time in the assist queue, for unsatisfied assists?
There's already a column for "Scheduler wait". In my experience, high levels of GC assist can lead to scheduler wait time for other goroutines — but maybe listing a non-zero value in the "GC pause" column would be enough to hint at that additional contributor to CPU starvation.
mknyszek
changed the title
cmd/trace: The time of "GC pause" column in the User-defined regions table is too large
cmd/trace: the "GC pause" column in the user-defined regions table doesn't make sense
Sep 6, 2023
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Use go tool trace's custom region to track function execution time.
Test Code: https://go.dev/play/p/idO-4ycK41K
What did you expect to see?
The actual pause time of goroutine due to GC.
What did you see instead?
The GC pause time is extremely large and does not match the time output by GODEBUG='gctrace=1'.
"GC pasue" uses the GCTime field, which corresponds to the GCDone event. It seems that this is the total GC time, and it is calculated for each goroutine.
cmd/trace/goroutines.go#L298
internal/trace/goroutines.go#L275
The text was updated successfully, but these errors were encountered: