1111require 'etc'
1212require 'yaml'
1313require_relative 'misc/stats'
14+ require_relative 'lib/cpu_config'
1415require_relative 'lib/benchmark_runner'
1516require_relative 'lib/table_formatter'
1617require_relative 'lib/benchmark_filter'
1718
18- # Checked system - error or return info if the command fails
19- def check_call ( command , env : { } , raise_error : true , quiet : false )
20- puts ( "+ #{ command } " ) unless quiet
21-
22- result = { }
23-
24- result [ :success ] = system ( env , command )
25- result [ :status ] = $?
26-
27- unless result [ :success ]
28- puts "Command #{ command . inspect } failed with exit code #{ result [ :status ] . exitstatus } in directory #{ Dir . pwd } "
29- raise RuntimeError . new if raise_error
30- end
31-
32- result
33- end
34-
35- def check_output ( *command )
36- IO . popen ( *command , &:read )
37- end
38-
3919def have_yjit? ( ruby )
40- ruby_version = check_output ( " #{ ruby } -v --yjit" , err : File ::NULL ) . strip
20+ ruby_version = ` #{ ruby } -v --yjit 2> #{ File ::NULL } ` . strip
4121 ruby_version . downcase . include? ( "yjit" )
4222end
4323
44- # Disable Turbo Boost while running benchmarks. Maximize the CPU frequency.
45- def set_bench_config ( turbo :)
46- # sudo requires the flag '-S' in order to take input from stdin
47- if File . exist? ( '/sys/devices/system/cpu/intel_pstate' ) # Intel
48- unless intel_no_turbo? || turbo
49- check_call ( "sudo -S sh -c 'echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo'" )
50- at_exit { check_call ( "sudo -S sh -c 'echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo'" , quiet : true ) }
51- end
52- # Disabling Turbo Boost reduces the CPU frequency, so this should be run after that.
53- check_call ( "sudo -S sh -c 'echo 100 > /sys/devices/system/cpu/intel_pstate/min_perf_pct'" ) unless intel_perf_100pct?
54- elsif File . exist? ( '/sys/devices/system/cpu/cpufreq/boost' ) # AMD
55- unless amd_no_boost? || turbo
56- check_call ( "sudo -S sh -c 'echo 0 > /sys/devices/system/cpu/cpufreq/boost'" )
57- at_exit { check_call ( "sudo -S sh -c 'echo 1 > /sys/devices/system/cpu/cpufreq/boost'" , quiet : true ) }
58- end
59- check_call ( "sudo -S cpupower frequency-set -g performance" ) unless performance_governor?
60- end
61- end
62-
63- def check_pstate ( turbo :)
64- if File . exist? ( '/sys/devices/system/cpu/intel_pstate' ) # Intel
65- unless turbo || intel_no_turbo?
66- puts ( "You forgot to disable turbo:" )
67- puts ( " sudo sh -c 'echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo'" )
68- exit ( -1 )
69- end
70-
71- unless intel_perf_100pct?
72- puts ( "You forgot to set the min perf percentage to 100:" )
73- puts ( " sudo sh -c 'echo 100 > /sys/devices/system/cpu/intel_pstate/min_perf_pct'" )
74- exit ( -1 )
75- end
76- elsif File . exist? ( '/sys/devices/system/cpu/cpufreq/boost' ) # AMD
77- unless turbo || amd_no_boost?
78- puts ( "You forgot to disable boost:" )
79- puts ( " sudo sh -c 'echo 0 > /sys/devices/system/cpu/cpufreq/boost'" )
80- exit ( -1 )
81- end
82-
83- unless performance_governor?
84- puts ( "You forgot to set the performance governor:" )
85- puts ( " sudo cpupower frequency-set -g performance" )
86- exit ( -1 )
87- end
88- end
89- end
90-
91- def intel_no_turbo?
92- File . read ( '/sys/devices/system/cpu/intel_pstate/no_turbo' ) . strip == '1'
93- end
94-
95- def intel_perf_100pct?
96- File . read ( '/sys/devices/system/cpu/intel_pstate/min_perf_pct' ) . strip == '100'
97- end
98-
99- def amd_no_boost?
100- File . read ( '/sys/devices/system/cpu/cpufreq/boost' ) . strip == '0'
101- end
102-
103- def performance_governor?
104- Dir . glob ( '/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor' ) . all? do |governor |
105- File . read ( governor ) . strip == 'performance'
106- end
107- end
108-
10924def mean ( values )
11025 Stats . new ( values ) . mean
11126end
@@ -132,10 +47,6 @@ def sort_benchmarks(bench_names)
13247 BenchmarkRunner . sort_benchmarks ( bench_names , benchmarks_metadata )
13348end
13449
135- def setarch_prefix
136- BenchmarkRunner . setarch_prefix
137- end
138-
13950# Run all the benchmarks and record execution times
14051def run_benchmarks ( ruby :, ruby_description :, categories :, name_filters :, out_path :, harness :, pre_init :, no_pinning :)
14152 bench_data = { }
@@ -193,7 +104,7 @@ def run_benchmarks(ruby:, ruby_description:, categories:, name_filters:, out_pat
193104 # Set up the benchmarking command
194105 cmd = [ ]
195106 if BenchmarkRunner . os == :linux
196- cmd += setarch_prefix
107+ cmd += BenchmarkRunner . setarch_prefix
197108
198109 # Pin the process to one given core to improve caching and reduce variance on CRuby
199110 # Other Rubies need to use multiple cores, e.g., for JIT threads
@@ -230,7 +141,7 @@ def run_benchmarks(ruby:, ruby_description:, categories:, name_filters:, out_pat
230141 end
231142
232143 # Do the benchmarking
233- result = check_call ( cmd . shelljoin , env : env , raise_error : false )
144+ result = BenchmarkRunner . check_call ( cmd . shelljoin , env : env , raise_error : false )
234145
235146 if result [ :success ]
236147 bench_data [ bench_name ] = JSON . parse ( File . read ( result_json_path ) ) . tap do |json |
@@ -387,18 +298,14 @@ def run_benchmarks(ruby:, ruby_description:, categories:, name_filters:, out_pat
387298 end
388299end
389300
390- # Disable CPU frequency scaling
391- set_bench_config ( turbo : args . turbo )
392-
393- # Check pstate status
394- check_pstate ( turbo : args . turbo )
301+ CPUConfig . configure_for_benchmarking ( turbo : args . turbo )
395302
396303# Create the output directory
397304FileUtils . mkdir_p ( args . out_path )
398305
399306ruby_descriptions = { }
400307args . executables . each do |name , executable |
401- ruby_descriptions [ name ] = check_output ( [ * executable , "-v" ] ) . chomp
308+ ruby_descriptions [ name ] = ` #{ executable . shelljoin } -v` . chomp
402309end
403310
404311# Benchmark with and without YJIT
0 commit comments