Skip to content

Commit

Permalink
Add benchmark for disabled zstd concurrency limit
Browse files Browse the repository at this point in the history
  • Loading branch information
rtreffer committed Sep 7, 2024
1 parent 9c89036 commit a77069f
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
3 changes: 2 additions & 1 deletion zstd.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var zstdAvailableEncoders sync.Map
var zstdCheckedOutEncoders int
var zstdMutex = &sync.Mutex{}
var zstdEncoderReturned = sync.NewCond(zstdMutex)
var zstdTestingDisableConcurrencyLimit bool

func getZstdEncoderChannel(params ZstdEncoderParams) chan *zstd.Encoder {
if c, ok := zstdAvailableEncoders.Load(params); ok {
Expand Down Expand Up @@ -47,7 +48,7 @@ func getZstdEncoder(params ZstdEncoderParams) *zstd.Encoder {
defer zstdMutex.Unlock()

limit := runtime.GOMAXPROCS(0)
for zstdCheckedOutEncoders >= limit {
for zstdCheckedOutEncoders >= limit && !zstdTestingDisableConcurrencyLimit {
zstdEncoderReturned.Wait()
limit = runtime.GOMAXPROCS(0)
}
Expand Down
54 changes: 53 additions & 1 deletion zstd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ func BenchmarkZstdMemoryConsumption(b *testing.B) {
// drain the buffered encoder so that we get a fresh one for the next run
zstdAvailableEncoders.Delete(params)
}

b.ReportMetric(float64(cpus), "(gomaxprocs)")
b.ReportMetric(float64(1), "(goroutines)")
}

// BenchmarkZstdMemoryConsumptionConcurrency benchmarks the memory consumption of the zstd encoder under the following constraints
Expand All @@ -49,11 +52,12 @@ func BenchmarkZstdMemoryConsumptionConcurrency(b *testing.B) {
}

cpus := 4
goroutines := 100
goroutines := 256

gomaxprocsBackup := runtime.GOMAXPROCS(cpus)
defer runtime.GOMAXPROCS(gomaxprocsBackup)

b.ReportMetric(float64(cpus), "(gomaxprocs)")
b.ResetTimer()
b.SetBytes(int64(len(buf) * goroutines))
b.ReportAllocs()
Expand All @@ -74,4 +78,52 @@ func BenchmarkZstdMemoryConsumptionConcurrency(b *testing.B) {
}
done.Wait()
}

b.ReportMetric(float64(cpus), "(gomaxprocs)")
b.ReportMetric(float64(goroutines), "(goroutines)")
}

// BenchmarkZstdMemoryNoConcurrencyLimit benchmarks the encoder behavior when the concurrency limit is disabled.
func BenchmarkZstdMemoryNoConcurrencyLimit(b *testing.B) {
zstdTestingDisableConcurrencyLimit = true
defer func() {
zstdTestingDisableConcurrencyLimit = false
}()

params := ZstdEncoderParams{Level: 9}
buf := make([]byte, 1024*1024)
for i := 0; i < len(buf); i++ {
buf[i] = byte((i / 256) + (i * 257))
}

cpus := 4
goroutines := 256

gomaxprocsBackup := runtime.GOMAXPROCS(cpus)
defer runtime.GOMAXPROCS(gomaxprocsBackup)

b.ReportMetric(float64(cpus), "(gomaxprocs)")
b.ResetTimer()
b.SetBytes(int64(len(buf) * goroutines))
b.ReportAllocs()
for i := 0; i < b.N; i++ {
// create n goroutines, wait until all start and then signal them to start compressing
var start sync.WaitGroup
var done sync.WaitGroup
start.Add(goroutines)
done.Add(goroutines)
for j := 0; j < goroutines; j++ {
go func() {
start.Done()
start.Wait()
_, _ = zstdCompress(params, nil, buf)
done.Done()
}()
zstdAvailableEncoders.Delete(params)
}
done.Wait()
}

b.ReportMetric(float64(cpus), "(gomaxprocs)")
b.ReportMetric(float64(goroutines), "(goroutines)")
}

0 comments on commit a77069f

Please sign in to comment.