Skip to content

Commit ad34b57

Browse files
Allow pinning to be specified in the benchmarks.yml
1 parent c783264 commit ad34b57

4 files changed

Lines changed: 23 additions & 6 deletions

File tree

benchmarks.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ knucleotide:
9393
desc: k-nucleotide from the Computer Language Benchmarks Game - counts nucleotide frequencies using hash tables in parallel using Process.fork
9494
knucleotide-ractor:
9595
desc: k-nucleotide from the Computer Language Benchmarks Game - counts nucleotide frequencies using hash tables in parallel using Ractors
96+
no_pinning: true
9697
lee:
9798
desc: lee is a circuit-board layout solver, deployed in a plausibly reality-like way
9899
matmul:

lib/argument_parser.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class ArgumentParser
1515
:rss,
1616
:graph,
1717
:no_pinning,
18+
:force_pinning,
1819
:turbo,
1920
:skip_yjit,
2021
:with_pre_init,
@@ -140,6 +141,10 @@ def parse(argv)
140141
args.no_pinning = true
141142
end
142143

144+
opts.on("--force-pinning", "force pinning even for benchmarks marked no_pinning") do
145+
args.force_pinning = true
146+
end
147+
143148
opts.on("--turbo", "don't disable CPU turbo boost") do
144149
args.turbo = true
145150
end
@@ -183,6 +188,7 @@ def default_args
183188
rss: false,
184189
graph: false,
185190
no_pinning: false,
191+
force_pinning: false,
186192
turbo: false,
187193
skip_yjit: false,
188194
with_pre_init: nil,

lib/benchmark_runner/cli.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ def run
3535
out_path: args.out_path,
3636
harness: args.harness,
3737
pre_init: args.with_pre_init,
38-
no_pinning: args.no_pinning
38+
no_pinning: args.no_pinning,
39+
force_pinning: args.force_pinning
3940
)
4041

4142
# Benchmark with and without YJIT

lib/benchmark_suite.rb

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,17 @@ class BenchmarkSuite
1919
RACTOR_CATEGORY = ["ractor"].freeze
2020
RACTOR_HARNESS = "harness-ractor"
2121

22-
attr_reader :categories, :name_filters, :excludes, :out_path, :harness, :pre_init, :no_pinning, :bench_dir, :ractor_bench_dir
22+
attr_reader :categories, :name_filters, :excludes, :out_path, :harness, :pre_init, :no_pinning, :force_pinning, :bench_dir, :ractor_bench_dir
2323

24-
def initialize(categories:, name_filters:, excludes: [], out_path:, harness:, pre_init: nil, no_pinning: false)
24+
def initialize(categories:, name_filters:, excludes: [], out_path:, harness:, pre_init: nil, no_pinning: false, force_pinning: false)
2525
@categories = categories
2626
@name_filters = name_filters
2727
@excludes = excludes
2828
@out_path = out_path
2929
@harness = harness
3030
@pre_init = pre_init ? expand_pre_init(pre_init) : nil
3131
@no_pinning = no_pinning
32+
@force_pinning = force_pinning
3233
@ractor_only = (categories == RACTOR_ONLY_CATEGORY)
3334

3435
setup_benchmark_directories
@@ -41,14 +42,14 @@ def run(ruby:, ruby_description:)
4142
bench_failures = {}
4243

4344
benchmark_entries = discover_benchmarks
44-
cmd_prefix = base_cmd(ruby_description)
4545
env = benchmark_env(ruby)
4646
caller_json_path = ENV["RESULT_JSON_PATH"]
4747

4848
benchmark_entries.each_with_index do |entry, idx|
4949
puts("Running benchmark \"#{entry.name}\" (#{idx+1}/#{benchmark_entries.length})")
5050

5151
result_json_path = caller_json_path || File.join(out_path, "temp#{Process.pid}.json")
52+
cmd_prefix = base_cmd(ruby_description, entry.name)
5253
result = run_single_benchmark(entry.script_path, result_json_path, ruby, cmd_prefix, env)
5354

5455
if result[:success]
@@ -199,13 +200,13 @@ def linux?
199200
end
200201

201202
# Set up the base command with CPU pinning if needed
202-
def base_cmd(ruby_description)
203+
def base_cmd(ruby_description, benchmark_name)
203204
if linux?
204205
cmd = setarch_prefix
205206

206207
# Pin the process to one given core to improve caching and reduce variance on CRuby
207208
# Other Rubies need to use multiple cores, e.g., for JIT threads
208-
if ruby_description.start_with?('ruby ') && !no_pinning
209+
if ruby_description.start_with?('ruby ') && should_pin?(benchmark_name)
209210
# The last few cores of Intel CPU may be slow E-Cores, so avoid using the last one.
210211
cpu = [(Etc.nprocessors / 2) - 1, 0].max
211212
cmd.concat(["taskset", "-c", "#{cpu}"])
@@ -217,6 +218,14 @@ def base_cmd(ruby_description)
217218
end
218219
end
219220

221+
def should_pin?(benchmark_name)
222+
return false if no_pinning
223+
return true if force_pinning
224+
225+
benchmark_meta = benchmarks_metadata[benchmark_name] || {}
226+
!benchmark_meta["no_pinning"]
227+
end
228+
220229
# Generate setarch prefix for Linux
221230
def setarch_prefix
222231
# Disable address space randomization (for determinism)

0 commit comments

Comments
 (0)