/
report.rb
305 lines (257 loc) · 10 KB
/
report.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This
# code is released under a tri EPL/GPL/LGPL license. You can use it,
# redistribute it and/or modify it under the terms of the:
#
# Eclipse Public License version 1.0
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1
time_budget = 60
reports = []
args = ARGV.dup
while not args.empty?
arg = args.shift
if arg.start_with? "-"
case arg
when "-s"
time_budget = args.shift.to_i
when "-m"
time_budget = args.shift.to_i * 60
when "-h"
time_budget = args.shift.to_i * 60 * 60
when "--help", "-help", "-h"
puts "JRUBY_DIR=... JRUBY_TRUFFLE_HEAD_DIR=... GRAAL_RELEASE_DIR=... GRAAL_HEAD_DIR=... ruby report.rb options reports..."
puts
puts " -s n run for n seconds (default 60)"
puts " -m n run for n minutes"
puts " -h n run for n hours"
puts
puts " report: all almost-all competition interpreters jruby jruby-master summary topaz other-vms"
puts
puts " Runs gnuplot, but you can also copy and paste the data files into Excel"
exit
else
puts "unknown argument " + arg
exit
end
else
if ["rbx", "topaz", "jruby", "jruby-master", "competition", "almost-all", "all", "interpreters", "summary", "other-vms", "head"].include? arg
reports.push(arg)
else
puts "unknown report " + arg
exit
end
end
end
if reports.empty?
reports.push("all")
end
report_references = {
"topaz" => "topaz-dev",
"rbx" => "rbx-2.2.6",
"jruby" => "jruby-1.7.12-server-indy",
"jruby-master" => "jruby-master-server-indy",
"competition" => "jruby-1.7.12-server-indy",
"almost-all" => "2.1.2",
"all" => "1.8.7-p375",
"interpreters" => "2.1.2",
"summary" => "2.1.2",
"other-vms" => "2.1.2",
"head" => "jruby-master+truffle-server"
}
Ruby = Struct.new(
:name,
:command,
:relevant_reports
)
rubies = []
["1.8.7-p375", "1.9.3-p547", "2.0.0-p481", "2.1.2", "ree-1.8.7-2012.02", "rbx-2.2.6"].each do |name|
dir = "~/.rbenv/versions/" + name
if Dir.exists? File.expand_path(dir)
relevant_reports = ["all"]
if ["1.8.7-p375", "1.9.3-p547", "2.0.0-p481", "2.1.2", "ree-1.8.7-2012.02"].include? name
relevant_reports.push("interpreters")
end
if ["2.1.2", "rbx-2.2.6"].include? name
relevant_reports.push("almost-all")
end
if name == "rbx-2.2.6"
relevant_reports.push("summary")
relevant_reports.push("competition")
relevant_reports.push("other-vms")
relevant_reports.push("rbx")
rubies.push Ruby.new(name + "-interpreter", dir + "/bin/ruby -Xint", ["all", "interpreters"])
end
if name == "2.1.2"
relevant_reports.push("summary")
relevant_reports.push("other-vms")
end
rubies.push Ruby.new(name, dir + "/bin/ruby", relevant_reports)
else
puts "warning: couldn't find " + dir
end
end
["jruby-1.7.12"].each do |name|
dir = "~/.rbenv/versions/" + name
if Dir.exists? File.expand_path(dir)
rubies.push Ruby.new(name + "-server-interpreter", dir + "/bin/jruby --server -Xcompile.mode=OFF", ["almost-all", "all", "jruby", "interpreters"])
rubies.push Ruby.new(name + "-server", dir + "/bin/jruby --server", ["almost-all", "all", "jruby"])
rubies.push Ruby.new(name + "-server-indy", dir + "/bin/jruby --server -Xcompile.invokedynamic=true", ["almost-all", "all", "competition", "jruby", "summary", "other-vms"])
else
puts "warning: couldn't find " + dir
end
end
if Dir.exists? File.expand_path("~/.rbenv/versions/topaz-dev")
rubies.push Ruby.new("topaz-dev", "~/.rbenv/versions/topaz-dev/bin/ruby", ["almost-all", "all", "competition", "topaz", "summary", "other-vms"])
else
puts "warning: couldn't find ~/.rbenv/versions/topaz-dev"
end
if not ENV["JRUBY_DIR"].nil? and not ENV["GRAAL_RELEASE_DIR"].nil? and Dir.exists? File.expand_path(ENV["JRUBY_DIR"]) and Dir.exists? File.expand_path(ENV["GRAAL_RELEASE_DIR"])
rubies.push Ruby.new("jruby-master-server-interpreter", "$JRUBY_DIR/bin/jruby --server -Xcompile.mode=OFF", ["almost-all", "all", "jruby", "jruby-master", "interpreters"])
rubies.push Ruby.new("jruby-master-server", "$JRUBY_DIR/bin/jruby --server", ["almost-all", "all", "jruby", "jruby-master"])
rubies.push Ruby.new("jruby-master-server-indy", "$JRUBY_DIR/bin/jruby --server -Xcompile.invokedynamic=true", ["almost-all", "all", "jruby", "jruby-master", "summary"])
rubies.push Ruby.new("jruby-master-server-ir-interpreter", "$JRUBY_DIR/bin/jruby --server -X-CIR", ["all", "jruby", "jruby-master", "interpreters"])
rubies.push Ruby.new("jruby-master-server-ir-compiler", "$JRUBY_DIR/bin/jruby --server -X+CIR", ["all", "jruby", "jruby-master"])
rubies.push Ruby.new("jruby-master+truffle-server-original", "JAVACMD=$GRAAL_RELEASE_DIR/bin/java $JRUBY_DIR/bin/jruby -J-original -X+T -Xtruffle.printRuntime=true", ["all", "interpreters", "jruby", "jruby-master"])
rubies.push Ruby.new("jruby-master+truffle-server", "JAVACMD=$GRAAL_RELEASE_DIR/bin/java $JRUBY_DIR/bin/jruby -J-server -X+T -Xtruffle.printRuntime=true", ["almost-all", "all", "jruby", "jruby-master", "topaz", "rbx", "competition", "summary", "other-vms", "head"])
else
puts "warning: couldn't find $JRUBY_DIR or $GRAAL_RELEASE_DIR"
end
if not ENV["JRUBY_TRUFFLE_HEAD_DIR"].nil? and not ENV["GRAAL_HEAD_DIR"].nil? and Dir.exists? File.expand_path(ENV["JRUBY_TRUFFLE_HEAD_DIR"]) and Dir.exists? File.expand_path(ENV["GRAAL_HEAD_DIR"])
rubies.push Ruby.new("jruby-truffle-head+truffle-server", "JAVACMD=$GRAAL_HEAD_DIR/jdk1.8.0/product/bin/java $JRUBY_TRUFFLE_HEAD_DIR/bin/jruby -J-server -X+T -Xtruffle.printRuntime=true", ["almost-all", "all", "jruby", "jruby-master", "topaz", "competition", "other-vms", "head"])
else
puts "warning: couldn't find $JRUBY_TRUFFLE_HEAD_DIR or $GRAAL_HEAD_DIR"
end
benchmarks = [
"binary-trees",
"fannkuch-redux",
"mandelbrot",
"n-body",
"pidigits",
"spectral-norm",
"neural-net",
"richards",
"deltablue"
]
disable_splitting = [
"spectral-norm",
"neural-net"
]
if reports == ["other-vms"]
benchmarks = ["mandelbrot"]
end
rubies_to_run = rubies.select do |ruby|
not (ruby.relevant_reports & reports).empty?
end
time_budget_per_run = time_budget / benchmarks.length / rubies_to_run.length
puts time_budget_per_run.to_s + "s for each combination of benchmark and implementation"
if time_budget_per_run < 10
puts "WARNING: time to run each benchmark is very low - increase the budget"
end
scores = {}
benchmarks.each do |benchmark|
scores[benchmark] = {}
rubies_to_run.each do |ruby|
if disable_splitting.include? benchmark and ruby.command.include? "-J-server"
splitting = "-J-G:-TruffleSplittingEnabled"
else
splitting = ""
end
output = `#{ruby.command} #{splitting} $JRUBY_DIR/bench/truffle/harness.rb -s #{time_budget_per_run} $JRUBY_DIR/bench/truffle/#{benchmark}.rb`
score_match = /[a-z\-]+: (\d+\.\d+)/.match(output)
if score_match.nil?
score = 0
puts benchmark + " " + ruby.name + " error"
puts output
else
score = score_match[1].to_f
puts benchmark + " " + ruby.name + " " + score.to_s
end
scores[benchmark][ruby.name] = score
end
end
if reports.include? "other-vms"
`echo budget = #{time_budget_per_run} > $JRUBY_DIR/bench/truffle/js/budget.js`
output = `v8 $JRUBY_DIR/bench/truffle/js/budget.js $JRUBY_DIR/bench/truffle/js/mandelbrot.js`
score_match = /(\d+\.\d+)/.match(output)
if score_match.nil?
score = 0
puts "mandelbrot v8 error"
puts output
else
score = score_match[1].to_f
puts "mandelbrot v8 #{score}"
end
scores["mandelbrot"]["v8"] = score
if not File.exist?(ENV["JRUBY_DIR"] + "/bench/truffle/java/Mandelbrot.class")
puts "warning: you need to build $JRUBY_DIR/bench/truffle/java/Mandelbrot.class"
end
output = `java -classpath $JRUBY_DIR/bench/truffle/java Mandelbrot #{time_budget_per_run}`
score_match = /(\d+\.\d+)/.match(output)
if score_match.nil?
score = 0
puts "mandelbrot java error"
puts output
else
score = score_match[1].to_f
puts "mandelbrot java #{score}"
end
scores["mandelbrot"]["java"] = score
if not File.exist?(ENV["JRUBY_DIR"] + "/bench/truffle/c/mandelbrot")
puts "warning: you need to build $JRUBY_DIR/bench/truffle/c/mandelbrot"
end
output = `$JRUBY_DIR/bench/truffle/c/mandelbrot #{time_budget_per_run}`
score_match = /(\d+\.\d+)/.match(output)
if score_match.nil?
score = 0
puts "mandelbrot c error"
puts output
else
score = score_match[1].to_f
puts "mandelbrot c #{score}"
end
scores["mandelbrot"]["c"] = score
end
def relative_to(benchmarks, scores, reference)
relative_scores = {}
benchmarks.each do |benchmark|
relative_scores[benchmark] = {}
reference_score = scores[benchmark][reference]
if reference_score == 0
puts "warning: reference score for #{benchmark} using #{reference} was zero"
end
scores[benchmark].each do |ruby, score|
if reference_score == 0
relative_scores[benchmark][ruby] = 0
else
relative_scores[benchmark][ruby] = score / reference_score
end
end
end
relative_scores
end
def plot(rubies_to_run, report, reference, benchmarks, scores)
sores_relative_reference = relative_to(benchmarks, scores, reference)
File.open("#{report}.data", "w") do |file|
header = ["Implementation"] + benchmarks
file.write(header.join(" ") + "\n")
rubies_to_run.each do |ruby|
if ruby.relevant_reports.include? report
line = [ruby.name]
benchmarks.each do |benchmark|
line.push(sores_relative_reference[benchmark][ruby.name])
end
file.write(line.join(" ") + "\n")
end
end
if report == "other-vms"
file.write("v8 #{sores_relative_reference["mandelbrot"]["v8"]}\n")
file.write("java #{sores_relative_reference["mandelbrot"]["java"]}\n")
file.write("c #{sores_relative_reference["mandelbrot"]["c"]}\n")
end
end
puts "gnuplot #{report}.gnuplot"
`gnuplot #{report}.gnuplot`
end
reports.each do |report|
plot(rubies_to_run, report, report_references[report], benchmarks, scores)
end