Skip to content

Commit

Permalink
executor: add cache padding for lock of RowContainer (pingcap#37627)
Browse files Browse the repository at this point in the history
  • Loading branch information
gengliqi authored Sep 7, 2022
1 parent be7de70 commit da05b4e
Showing 1 changed file with 14 additions and 7 deletions.
21 changes: 14 additions & 7 deletions util/chunk/row_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/pingcap/tidb/util/logutil"
"github.com/pingcap/tidb/util/memory"
"go.uber.org/zap"
"golang.org/x/sys/cpu"
)

type rowContainerRecord struct {
Expand All @@ -36,6 +37,8 @@ type rowContainerRecord struct {
}

type mutexForRowContainer struct {
// Add cache padding to avoid false sharing issue.
_ cpu.CacheLinePad
// RWMutex guarantees spill and get operator for rowContainer is mutually exclusive.
// `rLock` and `wLocks` is introduced to reduce the contention when multiple
// goroutine touch the same rowContainer concurrently. If there are multiple
Expand All @@ -44,9 +47,10 @@ type mutexForRowContainer struct {
// each goroutine. Thus each goroutine holds its own rLock but share the same
// underlying data, which can reduce the contention on m.rLock remarkably and
// get better performance.
rLock *sync.RWMutex
rLock sync.RWMutex
wLocks []*sync.RWMutex
records *rowContainerRecord
_ cpu.CacheLinePad
}

// Lock locks rw for writing.
Expand Down Expand Up @@ -86,16 +90,16 @@ type RowContainer struct {
// NewRowContainer creates a new RowContainer in memory.
func NewRowContainer(fieldType []*types.FieldType, chunkSize int) *RowContainer {
li := NewList(fieldType, chunkSize, chunkSize)
rLock := new(sync.RWMutex)
rc := &RowContainer{
m: &mutexForRowContainer{
records: &rowContainerRecord{inMemory: li},
rLock: rLock,
wLocks: []*sync.RWMutex{rLock},
rLock: sync.RWMutex{},
wLocks: []*sync.RWMutex{},
},
memTracker: memory.NewTracker(memory.LabelForRowContainer, -1),
diskTracker: disk.NewTracker(memory.LabelForRowContainer, -1),
}
rc.m.wLocks = append(rc.m.wLocks, &rc.m.rLock)
li.GetMemTracker().AttachTo(rc.GetMemTracker())
return rc
}
Expand All @@ -105,9 +109,12 @@ func NewRowContainer(fieldType []*types.FieldType, chunkSize int) *RowContainer
// holds an individual rLock.
func (c *RowContainer) ShallowCopyWithNewMutex() *RowContainer {
newRC := *c
rLock := new(sync.RWMutex)
c.m.wLocks = append(c.m.wLocks, rLock)
newRC.m.rLock = rLock
newRC.m = &mutexForRowContainer{
records: c.m.records,
rLock: sync.RWMutex{},
wLocks: []*sync.RWMutex{},
}
c.m.wLocks = append(c.m.wLocks, &newRC.m.rLock)
return &newRC
}

Expand Down

0 comments on commit da05b4e

Please sign in to comment.