Skip to content

Commit c3dda02

Browse files
committed
Better Ractor benching
1 parent c30874c commit c3dda02

File tree

2 files changed

+44
-31
lines changed

2 files changed

+44
-31
lines changed

benchmarks/binarytrees/benchmark.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,4 @@ def bench
4646

4747
require_relative '../../harness/loader'
4848

49-
run_benchmark(60) do
50-
Btree.bench
51-
end
49+
run_benchmark(60, Btree)

harness/harness.rb

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,40 +31,20 @@ def realtime
3131
Process.clock_gettime(Process::CLOCK_MONOTONIC) - r0
3232
end
3333

34-
def run_once(&block)
35-
if parallel = ENV["RACTOR_PARALLEL"]
36-
# block = Ractor.make_shareable(block)
37-
realtime do
38-
ractors = Integer(parallel).times.map do
39-
Ractor.new(&block)
40-
end
41-
ractors.each(&:join)
42-
end
43-
else
44-
realtime(&block)
45-
end
46-
end
47-
48-
# Takes a block as input
49-
def run_benchmark(_num_itrs_hint, &block)
34+
def run_benchmark_loop(runner, block, yjit_stats)
5035
times = []
5136
total_time = 0
5237
num_itrs = 0
53-
header = "itr: time"
54-
55-
RubyVM::YJIT.reset_stats! if defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
56-
57-
# If $YJIT_BENCH_STATS is given, print the diff of these stats at each iteration.
58-
if ENV["YJIT_BENCH_STATS"]
59-
yjit_stats = ENV["YJIT_BENCH_STATS"].split(",").map { |key| [key.to_sym, nil] }.to_h
60-
yjit_stats.each_key { |key| header << " #{key}" }
61-
end
62-
63-
puts header
6438
begin
6539
yjit_stats&.each_key { |key| yjit_stats[key] = RubyVM::YJIT.runtime_stats(key) }
6640

67-
time = run_once(&block)
41+
time = realtime do
42+
if runner
43+
runner.bench
44+
else
45+
block.call
46+
end
47+
end
6848
num_itrs += 1
6949

7050
# NOTE: we may want to avoid this as it could trigger GC?
@@ -84,6 +64,41 @@ def run_benchmark(_num_itrs_hint, &block)
8464
times << time
8565
total_time += time
8666
end until num_itrs >= WARMUP_ITRS + MIN_BENCH_ITRS and total_time >= MIN_BENCH_TIME
67+
[num_itrs, total_time, times.freeze].freeze
68+
end
69+
70+
# Takes a block as input
71+
def run_benchmark(_num_itrs_hint, runner = nil, &block)
72+
times = []
73+
total_time = 0
74+
num_itrs = 0
75+
header = "itr: time"
76+
77+
RubyVM::YJIT.reset_stats! if defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
78+
79+
# If $YJIT_BENCH_STATS is given, print the diff of these stats at each iteration.
80+
if ENV["YJIT_BENCH_STATS"]
81+
yjit_stats = ENV["YJIT_BENCH_STATS"].split(",").map { |key| [key.to_sym, nil] }.to_h.freeze
82+
yjit_stats.each_key { |key| header << " #{key}" }
83+
end
84+
85+
puts header
86+
if parallel = ENV["RACTOR_PARALLEL"]
87+
Warning[:experimental] = false
88+
ractors = Integer(parallel).times.map do
89+
Ractor.new(runner, block) do |runner, block|
90+
run_benchmark_loop(runner, block, nil)
91+
end
92+
end
93+
ractors.each do |ractor|
94+
r_num_itrs, r_total_time, r_times = Ractor.method_defined?(:value) ? ractor.value : ractor.take
95+
num_itrs += r_num_itrs
96+
total_time += r_total_time
97+
times += r_times
98+
end
99+
else
100+
num_itrs, total_time, times = run_benchmark_loop(runner, block, yjit_stats)
101+
end
87102

88103
warmup, bench = times[0...WARMUP_ITRS], times[WARMUP_ITRS..-1]
89104
return_results(warmup, bench)

0 commit comments

Comments
 (0)