Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 14 additions & 28 deletions lib/cpu_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

# Manages CPU frequency and turbo boost configuration for benchmark consistency
class CPUConfig
# These scripts are separate commands so that sudoers can allow just them
# with NOPASSWD, skipping the password prompt.
TURBO_BOOST_COMMAND = File.expand_path('../misc/turbo_boost', __dir__)
MAXIMIZE_FREQUENCY_COMMAND = File.expand_path('../misc/maximize_frequency', __dir__)

class << self
# Configure CPU for benchmarking: disable frequency scaling and verify settings
def configure_for_benchmarking(turbo:)
Expand Down Expand Up @@ -42,11 +47,14 @@ def frequency_maximized?
end

def disable_turbo_boost
# Override in subclasses
# sudo requires the flag '-S' in order to take input from stdin
BenchmarkRunner.check_call("sudo -S #{TURBO_BOOST_COMMAND} off")
at_exit { sudo_prefer_quiet("#{TURBO_BOOST_COMMAND} on") }
end

def maximize_frequency
# Override in subclasses
# Disabling Turbo Boost reduces the CPU frequency, so this should be run after that.
BenchmarkRunner.check_call("sudo -S #{MAXIMIZE_FREQUENCY_COMMAND}")
end

def check_pstate(turbo:)
Expand Down Expand Up @@ -75,17 +83,6 @@ class IntelCPUConfig < CPUConfig

private

def disable_turbo_boost
# sudo requires the flag '-S' in order to take input from stdin
BenchmarkRunner.check_call("sudo -S sh -c 'echo #{TURBO_DISABLED_VALUE} > #{NO_TURBO_PATH}'")
at_exit { sudo_prefer_quiet("sh -c 'echo 0 > #{NO_TURBO_PATH}'") }
end

def maximize_frequency
# Disabling Turbo Boost reduces the CPU frequency, so this should be run after that.
BenchmarkRunner.check_call("sudo -S sh -c 'echo #{FREQUENCY_MAXIMIZED_VALUE} > #{MIN_PERF_PCT_PATH}'")
end

def turbo_disabled?
@turbo_disabled ||= File.exist?(NO_TURBO_PATH) &&
File.read(NO_TURBO_PATH).strip == TURBO_DISABLED_VALUE
Expand All @@ -99,13 +96,13 @@ def frequency_maximized?
def check_pstate(turbo:)
unless turbo || turbo_disabled?
puts("You forgot to disable turbo:")
puts(" sudo sh -c 'echo #{TURBO_DISABLED_VALUE} > #{NO_TURBO_PATH}'")
puts(" sudo #{TURBO_BOOST_COMMAND} off")
exit(-1)
end

unless frequency_maximized?
puts("You forgot to set the min perf percentage to 100:")
puts(" sudo sh -c 'echo #{FREQUENCY_MAXIMIZED_VALUE} > #{MIN_PERF_PCT_PATH}'")
puts(" sudo #{MAXIMIZE_FREQUENCY_COMMAND}")
exit(-1)
end
end
Expand All @@ -117,21 +114,10 @@ class AMDCPUConfig < CPUConfig
BOOST_PATH = "#{CPUFREQ_DIR}/boost"
SCALING_GOVERNOR_GLOB = '/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor'
TURBO_DISABLED_VALUE = '0'
TURBO_ENABLED_VALUE = '1'
PERFORMANCE_GOVERNOR = 'performance'

private

def disable_turbo_boost
# sudo requires the flag '-S' in order to take input from stdin
BenchmarkRunner.check_call("sudo -S sh -c 'echo #{TURBO_DISABLED_VALUE} > #{BOOST_PATH}'")
at_exit { sudo_prefer_quiet("sh -c 'echo #{TURBO_ENABLED_VALUE} > #{BOOST_PATH}'") }
end

def maximize_frequency
BenchmarkRunner.check_call("sudo -S cpupower frequency-set -g performance")
end

def turbo_disabled?
@turbo_disabled ||= File.exist?(BOOST_PATH) &&
File.read(BOOST_PATH).strip == TURBO_DISABLED_VALUE
Expand All @@ -146,13 +132,13 @@ def frequency_maximized?
def check_pstate(turbo:)
unless turbo || turbo_disabled?
puts("You forgot to disable boost:")
puts(" sudo sh -c 'echo #{TURBO_DISABLED_VALUE} > #{BOOST_PATH}'")
puts(" sudo #{TURBO_BOOST_COMMAND} off")
exit(-1)
end

unless frequency_maximized?
puts("You forgot to set the performance governor:")
puts(" sudo cpupower frequency-set -g #{PERFORMANCE_GOVERNOR}")
puts(" sudo #{MAXIMIZE_FREQUENCY_COMMAND}")
exit(-1)
end
end
Expand Down
18 changes: 18 additions & 0 deletions misc/maximize_frequency
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/sh
# Maximize the minimum CPU frequency for stable benchmark results:
# min_perf_pct=100 on Intel pstate, or the performance governor on AMD cpufreq.
# run_benchmarks.rb runs this with sudo. Allowing this command in sudoers
# with NOPASSWD skips the password prompt.
set -eu

INTEL_MIN_PERF_PCT=/sys/devices/system/cpu/intel_pstate/min_perf_pct
AMD_BOOST=/sys/devices/system/cpu/cpufreq/boost

if [ -e "$INTEL_MIN_PERF_PCT" ]; then
echo 100 > "$INTEL_MIN_PERF_PCT"
elif [ -e "$AMD_BOOST" ]; then
cpupower frequency-set -g performance
else
echo "$0: no CPU frequency control found under /sys" >&2
exit 1
fi
23 changes: 23 additions & 0 deletions misc/turbo_boost
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/sh
# Enable or disable CPU turbo boost (Intel pstate or AMD cpufreq).
# run_benchmarks.rb runs this with sudo. Allowing this command in sudoers
# with NOPASSWD skips the password prompt.
set -eu

INTEL_NO_TURBO=/sys/devices/system/cpu/intel_pstate/no_turbo
AMD_BOOST=/sys/devices/system/cpu/cpufreq/boost

case "${1:-}" in
on) intel_value=0 amd_value=1 ;;
off) intel_value=1 amd_value=0 ;;
*) echo "Usage: $0 {on|off}" >&2; exit 1 ;;
esac

if [ -e "$INTEL_NO_TURBO" ]; then
echo "$intel_value" > "$INTEL_NO_TURBO"
elif [ -e "$AMD_BOOST" ]; then
echo "$amd_value" > "$AMD_BOOST"
else
echo "$0: no turbo boost control found under /sys" >&2
exit 1
fi
12 changes: 6 additions & 6 deletions test/cpu_config_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
end

assert_equal 1, cleanup_commands.length, "at_exit block should call check_call once"
assert_equal "sudo -n sh -c 'echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo'", cleanup_commands[0][:cmd]
assert_equal "sudo -n #{CPUConfig::TURBO_BOOST_COMMAND} on", cleanup_commands[0][:cmd]
assert_equal({ quiet: true, raise_error: false }, cleanup_commands[0][:opts])
end

Expand Down Expand Up @@ -192,7 +192,7 @@

assert_equal(-1, exit_code)
assert_includes output[0], "You forgot to disable turbo"
assert_includes output[0], "sudo sh -c 'echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo'"
assert_includes output[0], "sudo #{CPUConfig::TURBO_BOOST_COMMAND} off"
end

it 'exits when Intel min perf is not 100%' do
Expand Down Expand Up @@ -220,7 +220,7 @@

assert_equal(-1, exit_code)
assert_includes output[0], "You forgot to set the min perf percentage to 100"
assert_includes output[0], "sudo sh -c 'echo 100 > /sys/devices/system/cpu/intel_pstate/min_perf_pct'"
assert_includes output[0], "sudo #{CPUConfig::MAXIMIZE_FREQUENCY_COMMAND}"
end
end
end
Expand Down Expand Up @@ -306,7 +306,7 @@
end

assert_equal 1, cleanup_commands.length, "at_exit block should call check_call once"
assert_equal "sudo -n sh -c 'echo 1 > /sys/devices/system/cpu/cpufreq/boost'", cleanup_commands[0][:cmd]
assert_equal "sudo -n #{CPUConfig::TURBO_BOOST_COMMAND} on", cleanup_commands[0][:cmd]
assert_equal({ quiet: true, raise_error: false }, cleanup_commands[0][:opts])
end

Expand Down Expand Up @@ -337,7 +337,7 @@

assert_equal(-1, exit_code)
assert_includes output[0], "You forgot to disable boost"
assert_includes output[0], "sudo sh -c 'echo 0 > /sys/devices/system/cpu/cpufreq/boost'"
assert_includes output[0], "sudo #{CPUConfig::TURBO_BOOST_COMMAND} off"
end

it 'exits when AMD performance governor is not set' do
Expand Down Expand Up @@ -367,7 +367,7 @@

assert_equal(-1, exit_code)
assert_includes output[0], "You forgot to set the performance governor"
assert_includes output[0], "sudo cpupower frequency-set -g performance"
assert_includes output[0], "sudo #{CPUConfig::MAXIMIZE_FREQUENCY_COMMAND}"
end
end
end
Loading