Skip to content

Commit c864d12

Browse files
NullVoxPopuliclaude
andcommitted
Add CPU pinning and priority for local benchmarks
- New run-bench.sh wrapper: applies taskset -c 0 (CPU pinning) and nice -n -20 (high priority, when running as root) for pnpm bench - bench-compare.mjs: also uses nice -n -20 when running as root - local-bench-summary.sh: offers to apply CPU governor and boost fixes interactively instead of just warning Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
1 parent 87c663c commit c864d12

4 files changed

Lines changed: 73 additions & 5 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"lint:js": "eslint . --max-warnings=0",
2626
"lint:js:fix": "eslint . --fix --max-warnings=0",
2727
"lint:package": "publint",
28-
"bench": "node --expose-gc tests/parser.bench.mjs",
28+
"bench": "./scripts/run-bench.sh tests/parser.bench.mjs",
2929
"bench:compare": "node scripts/bench-compare.mjs",
3030
"bench:summary": "./scripts/local-bench-summary.sh",
3131
"test": "vitest run"

scripts/bench-compare.mjs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,19 +105,30 @@ try {
105105
CONTROL_DIR,
106106
];
107107

108-
// CPU pinning on Linux to reduce cross-core migration variance
108+
// CPU pinning + high priority on Linux for lower variance
109109
const IS_LINUX = process.platform === 'linux';
110110
const HAS_TASKSET = IS_LINUX && spawnSync('which', ['taskset'], { stdio: 'pipe' }).status === 0;
111+
const HAS_NICE = IS_LINUX && spawnSync('which', ['nice'], { stdio: 'pipe' }).status === 0;
111112

112113
let cmd = 'node';
113114
let fullArgs = benchArgs;
114115

115116
if (HAS_TASKSET) {
116117
cmd = 'taskset';
117118
fullArgs = ['-c', '0', 'node', ...benchArgs];
118-
console.error('📌 CPU pinning enabled (taskset -c 0)\n');
119+
console.error('📌 CPU pinning enabled (taskset -c 0)');
119120
}
120121

122+
if (HAS_NICE && process.getuid?.() === 0) {
123+
fullArgs = ['-n', '-20', cmd, ...fullArgs];
124+
cmd = 'nice';
125+
console.error('⚡ High priority enabled (nice -n -20)');
126+
} else if (HAS_NICE) {
127+
console.error('💡 Run with sudo for high scheduling priority (nice -n -20)');
128+
}
129+
130+
console.error('');
131+
121132
const result = spawnSync(cmd, fullArgs, {
122133
stdio: 'inherit',
123134
cwd: ROOT,

scripts/local-bench-summary.sh

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,54 @@
22

33
# Check CPU tuning on Linux — poor settings cause massive variance
44
hw_warnings=""
5+
hw_fixes=()
56

67
if [ -f /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor ]; then
78
gov=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)
89
if [ "$gov" != "performance" ]; then
910
hw_warnings+="⚠️ CPU governor is '$gov' — benchmark results will be noisy.
10-
Fix with: sudo cpupower frequency-set -g performance
1111
"
12+
hw_fixes+=("sudo cpupower frequency-set -g performance")
1213
fi
1314
fi
1415

1516
if [ -f /sys/devices/system/cpu/cpufreq/boost ]; then
1617
boost=$(cat /sys/devices/system/cpu/cpufreq/boost)
1718
if [ "$boost" = "1" ]; then
1819
hw_warnings+="⚠️ CPU boost is enabled — frequency varies with thermals.
19-
Fix with: echo 0 | sudo tee /sys/devices/system/cpu/cpufreq/boost
2020
"
21+
hw_fixes+=("echo 0 | sudo tee /sys/devices/system/cpu/cpufreq/boost")
22+
fi
23+
elif [ -f /sys/devices/system/cpu/intel_pstate/no_turbo ]; then
24+
no_turbo=$(cat /sys/devices/system/cpu/intel_pstate/no_turbo)
25+
if [ "$no_turbo" = "0" ]; then
26+
hw_warnings+="⚠️ Intel Turbo Boost is enabled — frequency varies with thermals.
27+
"
28+
hw_fixes+=("echo 1 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo")
2129
fi
2230
fi
2331

2432
if [ -n "$hw_warnings" ]; then
2533
echo ""
2634
echo "$hw_warnings"
35+
36+
if [ ${#hw_fixes[@]} -gt 0 ] && [ -t 0 ]; then
37+
echo "Fix with:"
38+
for fix in "${hw_fixes[@]}"; do
39+
echo " $fix"
40+
done
41+
echo ""
42+
read -rp "Apply these fixes now? [y/N] " answer
43+
if [[ "$answer" =~ ^[Yy]$ ]]; then
44+
for fix in "${hw_fixes[@]}"; do
45+
echo "$fix"
46+
eval "$fix"
47+
done
48+
echo ""
49+
echo "✅ CPU tuning applied."
50+
echo ""
51+
fi
52+
fi
2753
fi
2854

2955
export BENCH_JSON_OUTPUT=./bench-results.json

scripts/run-bench.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Wrapper that runs a node command with CPU pinning and high priority
4+
# when available, for lower-variance benchmarks.
5+
#
6+
# Usage: ./scripts/run-bench.sh <node args...>
7+
8+
set -euo pipefail
9+
10+
NODE_ARGS=("--expose-gc" "$@")
11+
12+
CMD=(node "${NODE_ARGS[@]}")
13+
14+
# CPU pinning on Linux — keep the process on a single core
15+
if command -v taskset &>/dev/null; then
16+
CMD=(taskset -c 0 "${CMD[@]}")
17+
echo "📌 CPU pinning enabled (taskset -c 0)" >&2
18+
fi
19+
20+
# High scheduling priority (best-effort, needs root for negative values)
21+
if command -v nice &>/dev/null; then
22+
if [ "$(id -u)" = "0" ]; then
23+
CMD=(nice -n -20 "${CMD[@]}")
24+
echo "⚡ High priority enabled (nice -n -20)" >&2
25+
else
26+
echo "💡 Run with sudo for high scheduling priority (nice -n -20)" >&2
27+
fi
28+
fi
29+
30+
echo "" >&2
31+
exec "${CMD[@]}"

0 commit comments

Comments
 (0)