Skip to content

Commit 9d1988d

Browse files
authored
stream: group bool fields at tail of clientStream to reduce allocator size class 288B→256B (grpc#9281)
1 parent cecd55a commit 9d1988d

1 file changed

Lines changed: 23 additions & 16 deletions

File tree

stream.go

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -689,30 +689,17 @@ type clientStream struct {
689689

690690
cancel context.CancelFunc // cancels all attempts
691691

692-
sentLast bool // sent an end stream
693-
694-
receivedFirstMsg bool // set after the first message is received
695-
696692
methodConfig *MethodConfig
697693

698694
ctx context.Context // the application's context, wrapped by stats/tracing
699695

700696
retryThrottler *retryThrottler // The throttler active when the RPC began.
701697

702698
binlogs []binarylog.MethodLogger
703-
// serverHeaderBinlogged is a boolean for whether server header has been
704-
// logged. Server header will be logged when the first time one of those
705-
// happens: stream.Header(), stream.Recv().
706-
//
707-
// It's only read and used by Recv() and Header(), so it doesn't need to be
708-
// synchronized.
709-
serverHeaderBinlogged bool
710699

711700
mu sync.Mutex
712-
firstAttempt bool // if true, transparent retry is valid
713-
numRetries int // exclusive of transparent retry attempt(s)
714-
numRetriesSincePushback int // retries since pushback; to reset backoff
715-
finished bool // TODO: replace with atomic cmpxchg or sync.Once?
701+
numRetries int // exclusive of transparent retry attempt(s)
702+
numRetriesSincePushback int // retries since pushback; to reset backoff
716703
// attempt is the active client stream attempt.
717704
// The only place where it is written is the newAttemptLocked method and this method never writes nil.
718705
// So, attempt can be nil only inside newClientStream function when clientStream is first created.
@@ -722,13 +709,33 @@ type clientStream struct {
722709
// place where we need to check if the attempt is nil.
723710
attempt *csAttempt
724711
// TODO(hedging): hedging will have multiple attempts simultaneously.
725-
committed bool // active attempt committed for retry?
726712
onCommit func()
727713
replayBuffer []replayOp // operations to replay on retry
728714
replayBufferSize int // current size of replayBuffer
715+
716+
// Bool fields are grouped at the tail to eliminate the alignment padding
717+
// that would otherwise follow each bool when the next field is pointer- or
718+
// int-sized. See https://github.com/grpc/grpc-go/issues/9280 for benchmarks.
719+
// Add new bool fields here, not inline above.
720+
721+
// Not guarded by mu.
722+
sentLast bool // sent an end stream
723+
receivedFirstMsg bool // set after the first message is received
724+
// serverHeaderBinlogged is a boolean for whether server header has been
725+
// logged. Server header will be logged when the first time one of those
726+
// happens: stream.Header(), stream.Recv().
727+
//
728+
// It's only read and used by Recv() and Header(), so it doesn't need to be
729+
// synchronized.
730+
serverHeaderBinlogged bool
729731
// nameResolutionDelay indicates if there was a delay in the name resolution.
730732
// This field is only valid on client side, it's always false on server side.
731733
nameResolutionDelay bool
734+
735+
// Guarded by mu.
736+
firstAttempt bool // if true, transparent retry is valid
737+
finished bool // TODO: replace with atomic cmpxchg or sync.Once?
738+
committed bool // active attempt committed for retry?
732739
}
733740

734741
type replayOp struct {

0 commit comments

Comments
 (0)