Skip to content

Commit 8b2f879

Browse files
committed
refactor: improve local development resilience and add SKIP_TUNE
- Make CPU pinning (cpuset-cpus) dynamic based on host core count - Add SKIP_TUNE environment variable to bypass sudo-required system tuning - Update documentation to reflect new dynamic defaults and configuration options
1 parent 5e3b115 commit 8b2f879

4 files changed

Lines changed: 41 additions & 5 deletions

File tree

scripts/benchmark.sh

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,11 @@ cleanup_all() {
9090
docker volume prune -f >/dev/null 2>&1 || true
9191
docker image prune -f >/dev/null 2>&1 || true
9292
}
93-
trap 'cleanup_all; system_restore' EXIT
93+
if [ "${SKIP_TUNE:-}" != "true" ]; then
94+
trap 'cleanup_all; system_restore' EXIT
95+
else
96+
trap 'cleanup_all' EXIT
97+
fi
9498

9599
# Clean slate: stop any leftover benchmark containers from a previous
96100
# crashed run, AND prune any leftover dangling volumes/images from the
@@ -171,7 +175,11 @@ $_has_isolated_test && framework_build
171175

172176
# ── System tuning — NOW, after all image builds are complete ───────────────
173177

174-
system_tune
178+
if [ "${SKIP_TUNE:-}" != "true" ]; then
179+
system_tune
180+
else
181+
info "skipping system tuning as requested (SKIP_TUNE=true)"
182+
fi
175183

176184
# Start the postgres sidecar if any subscribed test needs it.
177185
need_pg=false

scripts/lib/common.sh

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,23 @@ H3THREADS="${H3THREADS:-64}"
2929
GCANNON="${GCANNON:-gcannon}"
3030
GCANNON_IMAGE="${GCANNON_IMAGE:-gcannon:latest}"
3131
GCANNON_MODE="${GCANNON_MODE:-native}"
32-
GCANNON_CPUS="${GCANNON_CPUS:-32-63,96-127}"
32+
33+
_AVAIL_CORES=$(nproc 2>/dev/null || echo 1)
34+
if [ -z "${GCANNON_CPUS:-}" ]; then
35+
if [ "$_AVAIL_CORES" -ge 128 ]; then
36+
GCANNON_CPUS="32-63,96-127"
37+
else
38+
# For smaller machines, just use the second half of cores for load gen,
39+
# or all cores if we only have 1 or 2.
40+
if [ "$_AVAIL_CORES" -le 2 ]; then
41+
GCANNON_CPUS="0-$((_AVAIL_CORES - 1))"
42+
else
43+
_HALF=$((_AVAIL_CORES / 2))
44+
GCANNON_CPUS="$_HALF-$((_AVAIL_CORES - 1))"
45+
fi
46+
fi
47+
fi
48+
export GCANNON_CPUS
3349

3450
H2LOAD="${H2LOAD:-h2load}"
3551
H2LOAD_IMAGE="${H2LOAD_IMAGE:-h2load:latest}"

scripts/lib/framework.sh

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,18 @@ framework_start() {
9595
# Profile-declared CPU limit.
9696
if [ -n "$cpu_limit" ]; then
9797
if [[ "$cpu_limit" == *-* ]]; then
98-
args+=(--cpuset-cpus="$cpu_limit")
98+
local max_cpu
99+
max_cpu=$(($(nproc)-1))
100+
# Extract the largest CPU index from the cpuset string (e.g. "95" from "0-31,64-95")
101+
local requested_max
102+
requested_max=$(echo "$cpu_limit" | grep -oP '\d+$')
103+
104+
if [ "$requested_max" -gt "$max_cpu" ]; then
105+
warn "profile cpuset $cpu_limit exceeds available CPUs (max $max_cpu) — using all cores"
106+
args+=(--cpus="$(nproc)")
107+
else
108+
args+=(--cpuset-cpus="$cpu_limit")
109+
fi
99110
else
100111
local avail
101112
avail=$(nproc 2>/dev/null || echo 64)

site/content/docs/running-locally/configuration.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Defined in `scripts/lib/common.sh`. Override by exporting before you run the scr
1616
| `THREADS` | `64` | gcannon / wrk worker threads. |
1717
| `H2THREADS` | `64` | h2load worker threads (HTTP/2, h2c gRPC). |
1818
| `H3THREADS` | `64` | h2load-h3 worker threads (HTTP/3 over QUIC). |
19+
| `SKIP_TUNE` | `false` | When `true`, skips kernel/hardware tuning (CPU governor, socket limits) that requires `sudo`. Useful for local development. |
1920

2021
In `benchmark-lite.sh`, `THREADS` defaults to `max(nproc / 2, 1)` and `H2THREADS` / `H3THREADS` mirror `$THREADS`. Pass `--load-threads N` to override all three in one shot.
2122

@@ -36,7 +37,7 @@ Every framework `Dockerfile` reads the same defaults from its env, so you rarely
3637
|---|---|---|
3738
| `LOADGEN_DOCKER` | `false` | When `true`, every load generator runs from its Docker image instead of the host binary. Builds missing images automatically from `docker/*.Dockerfile`. Forced `true` by `benchmark-lite.sh`. |
3839
| `GCANNON_MODE` | `native` | `native` or `docker`. Implied by `LOADGEN_DOCKER`. |
39-
| `GCANNON_CPUS` | `32-63,96-127` | CPU list the load generators run on. Native mode wraps calls in `taskset -c $GCANNON_CPUS`; docker mode passes it via `--cpuset-cpus`. `benchmark-lite.sh` sets this to `0-$((nproc-1))`. |
40+
| `GCANNON_CPUS` | dynamic | CPU list the load generators run on. Native mode wraps calls in `taskset -c $GCANNON_CPUS`; docker mode passes it via `--cpuset-cpus`. Defaults to the upper half of available cores on smaller machines to avoid resource contention with the server. |
4041

4142
## Tool binaries and images
4243

0 commit comments

Comments
 (0)