mirror of
https://github.com/hanzoai/visor.git
synced 2026-09-24 17:04:14 +00:00
The current systrap fastpath heuristics do a good job getting high
performance when there are idle CPUs, but fail when there are not
enough and do much worse then even the "pure slowpath".
Here is a summary of changes made to remedy that:
1. Disable stub and dispatcher fastpath by default.
2. Decouple fastpath states to be separate between dispatcher and stub
fastpath.
3. Implement response latency metrics for both sentry->stub and
stub->sentry messages. Use these latency metrics in order keep track of
the baseline latency for both sides. With baseline latency established,
compare fastpath latency to determine how beneficial it is to keep
fastpath enabled.
Some sampled benchmarks:
- sysbench-X-Y:
```
```
- gettid_benchmark
- getpid_benchmark
Some benchmark results (5-run average):
- On a 4 core machine:
[]() | HEAD | ThisCL
-------------------|----------|-----------
sysbench-1-8: | 48218ms | 50282ms
sysbench-2-4: | 65900ms | 72282ms
sysbench-4-2: |427880ms | 175714ms
sysbench-1-2: | 12998ms | 13688ms
getpid_benchmark: (HEAD)
```
Benchmark Time CPU Iterations
-------------------------------------------------------
BM_Getpid 3471 ns 3441 ns 212121
BM_GetpidOpt 1039 ns 1029 ns 700000
```
getpid_benchmark: (This CL)
```
Benchmark Time CPU Iterations
-------------------------------------------------------
BM_Getpid 3718 ns 3600 ns 200000
BM_GetpidOpt 1320 ns 1281 ns 538462
```
gettid_benchmark: Like getpid, this CL slightly slower on lower thread count
test variants.
- On a 1 core machine:
getpid_benchmark: (HEAD)
```
Benchmark Time CPU Iterations
-------------------------------------------------------
BM_Getpid 74868 ns 75000 ns 10000
BM_GetpidOpt 74463 ns 74286 ns 8750
```
getpid_benchmark: (This CL)
```
Benchmark Time CPU Iterations
-------------------------------------------------------
BM_Getpid 12425 ns 12443 ns 53846
BM_GetpidOpt 8645 ns 8686 ns 87500
```
gettid_benchmark: Same trend as for getpid_benchmark across the board.
Another interesting case to look at for 1-core machines is copying one large file:
```
./runsc --rootless --network none --ignore-cgroups do --force-overlay=false sh -c "time head -c 1073741824 </dev/zero >full-file"
```
- file copy (HEAD): 36.07user 0.00system 0:36.44elapsed 98%CPU
- file copy (This CL): 2.96user 0.23system 0:07.14elapsed 44%CPU
Fixes #9119.
PiperOrigin-RevId: 576600019
61 lines
1.8 KiB
Go
61 lines
1.8 KiB
Go
// Copyright 2023 The gVisor Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
//go:build systrap_profiling
|
|
// +build systrap_profiling
|
|
|
|
package systrap
|
|
|
|
import (
|
|
"gvisor.dev/gvisor/pkg/metric"
|
|
)
|
|
|
|
// SystrapProfiling is a builder that produces conditionally compiled metrics.
|
|
// Metrics made from this are compiled and active at runtime when the
|
|
// "systrap_profiling" go-tag is specified at compilation.
|
|
var SystrapProfiling = metric.RealMetricBuilder{}
|
|
|
|
//go:nosplit
|
|
func updateDebugMetrics(stubBoundLat, sentryBoundLat cpuTicks) {
|
|
if stubBoundLat == 0 {
|
|
} else if stubBoundLat < 2000 {
|
|
stubLatWithin1kUS.Increment()
|
|
} else if stubBoundLat < 10000 {
|
|
stubLatWithin5kUS.Increment()
|
|
} else if stubBoundLat < 20000 {
|
|
stubLatWithin10kUS.Increment()
|
|
} else if stubBoundLat < 40000 {
|
|
stubLatWithin20kUS.Increment()
|
|
} else if stubBoundLat < 80000 {
|
|
stubLatWithin40kUS.Increment()
|
|
} else {
|
|
stubLatGreater40kUS.Increment()
|
|
}
|
|
|
|
if sentryBoundLat == 0 {
|
|
} else if sentryBoundLat < 2000 {
|
|
sentryLatWithin1kUS.Increment()
|
|
} else if sentryBoundLat < 10000 {
|
|
sentryLatWithin5kUS.Increment()
|
|
} else if sentryBoundLat < 20000 {
|
|
sentryLatWithin10kUS.Increment()
|
|
} else if sentryBoundLat < 40000 {
|
|
sentryLatWithin20kUS.Increment()
|
|
} else if sentryBoundLat < 80000 {
|
|
sentryLatWithin40kUS.Increment()
|
|
} else {
|
|
sentryLatGreater40kUS.Increment()
|
|
}
|
|
}
|