Skip to content

Commit b17f4b5

Browse files
committed
workload: reduce RNG allocations
PR cockroachdb#143626 removed `golang.org/x/exp/rand` in favor of `math/rand/v2`. The number of heap allocations grew dramatically due to new calls to `rand.New` and `rand.NewPCG`. This commit eliminates these allocations by reusing allocations of `rand.Rand` and `rand.PCG`. ``` name old time/op new time/op delta InitialData/tpcc/warehouses=1 103ms ± 0% 91ms ± 0% -11.96% (p=0.016 n=4+5) name old speed new speed delta InitialData/tpcc/warehouses=1 2.13GB/s ± 0% 2.50GB/s ± 0% +17.58% (p=0.016 n=4+5) name old alloc/op new alloc/op delta InitialData/tpcc/warehouses=1 10.3MB ± 0% 0.1MB ± 0% -99.24% (p=0.008 n=5+5) name old allocs/op new allocs/op delta InitialData/tpcc/warehouses=1 640k ± 0% 0k ± 0% -99.97% (p=0.008 n=5+5) ``` Release note: None
1 parent a17793d commit b17f4b5

2 files changed

Lines changed: 21 additions & 8 deletions

File tree

pkg/workload/tpcc/generate.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ var itemTypes = []*types.T{
7272
func (w *tpcc) tpccItemInitialRowBatch(rowIdx int, cb coldata.Batch, a *bufalloc.ByteAllocator) {
7373
l := w.localsPool.Get().(*generateLocals)
7474
defer w.localsPool.Put(l)
75-
l.rng.Rand = rand.New(rand.NewPCG(RandomSeed.Seed(), uint64(rowIdx)))
75+
l.rng.Seed(RandomSeed.Seed(), uint64(rowIdx))
7676
ao := aCharsOffset(l.rng.IntN(len(aCharsAlphabet)))
7777

7878
iID := rowIdx + 1
@@ -115,7 +115,7 @@ func (w *tpcc) tpccWarehouseInitialRowBatch(
115115
) {
116116
l := w.localsPool.Get().(*generateLocals)
117117
defer w.localsPool.Put(l)
118-
l.rng.Rand = rand.New(rand.NewPCG(RandomSeed.Seed(), uint64(rowIdx)))
118+
l.rng.Seed(RandomSeed.Seed(), uint64(rowIdx))
119119
no := numbersOffset(l.rng.IntN(len(numbersAlphabet)))
120120
lo := lettersOffset(l.rng.IntN(len(lettersAlphabet)))
121121

@@ -173,7 +173,7 @@ var stockTypes = []*types.T{
173173
func (w *tpcc) tpccStockInitialRowBatch(rowIdx int, cb coldata.Batch, a *bufalloc.ByteAllocator) {
174174
l := w.localsPool.Get().(*generateLocals)
175175
defer w.localsPool.Put(l)
176-
l.rng.Rand = rand.New(rand.NewPCG(RandomSeed.Seed(), uint64(rowIdx)))
176+
l.rng.Seed(RandomSeed.Seed(), uint64(rowIdx))
177177
ao := aCharsOffset(l.rng.IntN(len(aCharsAlphabet)))
178178

179179
sID := (rowIdx % numStockPerWarehouse) + 1
@@ -245,7 +245,7 @@ func (w *tpcc) tpccDistrictInitialRowBatch(
245245
) {
246246
l := w.localsPool.Get().(*generateLocals)
247247
defer w.localsPool.Put(l)
248-
l.rng.Rand = rand.New(rand.NewPCG(RandomSeed.Seed(), uint64(rowIdx)))
248+
l.rng.Seed(RandomSeed.Seed(), uint64(rowIdx))
249249
ao := aCharsOffset(l.rng.IntN(len(aCharsAlphabet)))
250250
no := numbersOffset(l.rng.IntN(len(numbersAlphabet)))
251251
lo := lettersOffset(l.rng.IntN(len(lettersAlphabet)))
@@ -318,7 +318,7 @@ func (w *tpcc) tpccCustomerInitialRowBatch(
318318
) {
319319
l := w.localsPool.Get().(*generateLocals)
320320
defer w.localsPool.Put(l)
321-
l.rng.Rand = rand.New(rand.NewPCG(RandomSeed.Seed(), uint64(rowIdx)))
321+
l.rng.Seed(RandomSeed.Seed(), uint64(rowIdx))
322322
ao := aCharsOffset(l.rng.IntN(len(aCharsAlphabet)))
323323
no := numbersOffset(l.rng.IntN(len(numbersAlphabet)))
324324
lo := lettersOffset(l.rng.IntN(len(lettersAlphabet)))
@@ -416,7 +416,7 @@ var historyTypes = []*types.T{
416416
func (w *tpcc) tpccHistoryInitialRowBatch(rowIdx int, cb coldata.Batch, a *bufalloc.ByteAllocator) {
417417
l := w.localsPool.Get().(*generateLocals)
418418
defer w.localsPool.Put(l)
419-
l.rng.Rand = rand.New(rand.NewPCG(RandomSeed.Seed(), uint64(rowIdx)))
419+
l.rng.Seed(RandomSeed.Seed(), uint64(rowIdx))
420420
ao := aCharsOffset(l.rng.IntN(len(aCharsAlphabet)))
421421

422422
// This used to be a V4 uuid made through the normal `uuid.MakeV4`
@@ -481,7 +481,7 @@ func (w *tpcc) tpccOrderInitialRowBatch(rowIdx int, cb coldata.Batch, a *bufallo
481481

482482
// NB: numOrderLines is not allowed to use precomputed random data, make sure
483483
// it stays that way. See 4.3.2.1.
484-
l.rng.Rand = rand.New(rand.NewPCG(RandomSeed.Seed(), uint64(rowIdx)))
484+
l.rng.Seed(RandomSeed.Seed(), uint64(rowIdx))
485485
numOrderLines := randInt(l.rng.Rand, minOrderLinesPerOrder, maxOrderLinesPerOrder)
486486

487487
oID := (rowIdx % numOrdersPerDistrict) + 1
@@ -602,7 +602,7 @@ func (w *tpcc) tpccOrderLineInitialRowBatch(
602602

603603
// NB: numOrderLines is not allowed to use precomputed random data, make sure
604604
// it stays that way. See 4.3.2.1.
605-
l.rng.Rand = rand.New(rand.NewPCG(RandomSeed.Seed(), uint64(orderRowIdx)))
605+
l.rng.Seed(RandomSeed.Seed(), uint64(orderRowIdx))
606606
numOrderLines := int(randInt(l.rng.Rand, minOrderLinesPerOrder, maxOrderLinesPerOrder))
607607

608608
// NB: There is one batch of order_line rows per order

pkg/workload/tpcc/random.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const numbersAlphabet = `1234567890`
3232

3333
type tpccRand struct {
3434
*rand.Rand
35+
*rand.PCG
3536

3637
aChars, letters, numbers workloadimpl.PrecomputedRand
3738
}
@@ -40,6 +41,18 @@ type aCharsOffset int
4041
type lettersOffset int
4142
type numbersOffset int
4243

44+
// Seed resets the RNG with the given seeds.
45+
func (rng *tpccRand) Seed(seed1, seed2 uint64) {
46+
if rng.PCG != nil {
47+
// rand.Rand has no state other than the source, so we don't need to
48+
// recreate it.
49+
rng.PCG.Seed(seed1, seed2)
50+
return
51+
}
52+
rng.PCG = rand.NewPCG(seed1, seed2)
53+
rng.Rand = rand.New(rng.PCG)
54+
}
55+
4356
func randStringFromAlphabet(
4457
rng *rand.Rand,
4558
a *bufalloc.ByteAllocator,

0 commit comments

Comments
 (0)