mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: use per-goroutine sequence numbers in tracer
Currently tracer uses global sequencer and it introduces significant slowdown on parallel machines (up to 10x). Replace the global sequencer with per-goroutine sequencer. If we assign per-goroutine sequence numbers to only 3 types of events (start, unblock and syscall exit), it is enough to restore consistent partial ordering of all events. Even these events don't need sequence numbers all the time (if goroutine starts on the same P where it was unblocked, then start does not need sequence number). The burden of restoring the order is put on trace parser. Details of the algorithm are described in the comments. On http benchmark with GOMAXPROCS=48: no tracing: 5026 ns/op tracing: 27803 ns/op (+453%) with this change: 6369 ns/op (+26%, mostly for traceback) Also trace size is reduced by ~22%. Average event size before: 4.63 bytes/event, after: 3.62 bytes/event. Besides running trace tests, I've also tested with manually broken cputicks (random skew for each event, per-P skew and episodic random skew). In all cases broken timestamps were detected and no test failures. Change-Id: I078bde421ccc386a66f6c2051ab207bcd5613efa Reviewed-on: https://go-review.googlesource.com/21512 Run-TryBot: Dmitry Vyukov <dvyukov@google.com> Reviewed-by: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
ba966f5d89
commit
a3703618ea
6 changed files with 479 additions and 184 deletions
|
|
@ -332,16 +332,17 @@ type g struct {
|
|||
waitsince int64 // approx time when the g become blocked
|
||||
waitreason string // if status==Gwaiting
|
||||
schedlink guintptr
|
||||
preempt bool // preemption signal, duplicates stackguard0 = stackpreempt
|
||||
paniconfault bool // panic (instead of crash) on unexpected fault address
|
||||
preemptscan bool // preempted g does scan for gc
|
||||
gcscandone bool // g has scanned stack; protected by _Gscan bit in status
|
||||
gcscanvalid bool // false at start of gc cycle, true if G has not run since last scan
|
||||
throwsplit bool // must not split stack
|
||||
raceignore int8 // ignore race detection events
|
||||
sysblocktraced bool // StartTrace has emitted EvGoInSyscall about this goroutine
|
||||
sysexitticks int64 // cputicks when syscall has returned (for tracing)
|
||||
sysexitseq uint64 // trace seq when syscall has returned (for tracing)
|
||||
preempt bool // preemption signal, duplicates stackguard0 = stackpreempt
|
||||
paniconfault bool // panic (instead of crash) on unexpected fault address
|
||||
preemptscan bool // preempted g does scan for gc
|
||||
gcscandone bool // g has scanned stack; protected by _Gscan bit in status
|
||||
gcscanvalid bool // false at start of gc cycle, true if G has not run since last scan
|
||||
throwsplit bool // must not split stack
|
||||
raceignore int8 // ignore race detection events
|
||||
sysblocktraced bool // StartTrace has emitted EvGoInSyscall about this goroutine
|
||||
sysexitticks int64 // cputicks when syscall has returned (for tracing)
|
||||
traceseq uint64 // trace event sequencer
|
||||
tracelastp puintptr // last P emitted an event for this goroutine
|
||||
lockedm *m
|
||||
sig uint32
|
||||
writebuf []byte
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue