Skip to content

Commit d495421

Browse files
committed
Report startup in harness.py
1 parent 1b8f63e commit d495421

File tree

4 files changed

+618
-10
lines changed

4 files changed

+618
-10
lines changed

graalpython/com.oracle.graal.python.benchmarks/python/harness.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ def _as_int(value):
196196

197197

198198
class BenchRunner(object):
199-
def __init__(self, bench_file, bench_args=None, iterations=1, warmup=-1, warmup_runs=0, startup=False):
199+
def __init__(self, bench_file, bench_args=None, iterations=1, warmup=-1, warmup_runs=0, startup=None):
200200
assert isinstance(iterations, int), \
201201
"BenchRunner iterations argument must be an int, got %s instead" % iterations
202202
assert isinstance(warmup, int), \
@@ -276,25 +276,31 @@ def run(self):
276276
report_startup = GRAALPYTHON and self.startup and __graalpython__.startup_nano != -1
277277

278278
bench_func = self._get_attr(ATTR_BENCHMARK)
279-
startup = -1
279+
startup_ns = -1
280+
early_warmup_ns = -1
281+
late_warmup_ns = -1
280282
durations = []
281283
if bench_func and hasattr(bench_func, '__call__'):
282284
if self.warmup_runs:
283285
print("### (pre)warming up for %s iterations ... " % self.warmup_runs)
284286
for _ in range(self.warmup_runs):
285287
bench_func(*args)
286288
cur_time_nano = monotonic_ns()
287-
if report_startup and startup == -1:
288-
startup = cur_time_nano - __graalpython__.startup_nano
289+
if report_startup and startup_ns == -1:
290+
startup_ns = cur_time_nano - __graalpython__.startup_nano
289291
self._call_attr(ATTR_CLEANUP, *args)
290292

291293
for iteration in range(self.iterations):
292294
start = time()
293295
bench_func(*args)
294296
cur_time_nano = monotonic_ns()
295297
duration = time() - start
296-
if report_startup and startup == -1:
297-
startup = cur_time_nano - __graalpython__.startup_nano
298+
if report_startup and startup_ns == -1 and iteration == self.startup[0] - 1:
299+
startup_ns = cur_time_nano - __graalpython__.startup_nano
300+
if report_startup and early_warmup_ns == -1 and iteration == self.startup[1] - 1:
301+
early_warmup_ns = cur_time_nano - __graalpython__.startup_nano
302+
if report_startup and late_warmup_ns == -1 and iteration == self.startup[2] - 1:
303+
late_warmup_ns = cur_time_nano - __graalpython__.startup_nano
298304
durations.append(duration)
299305
duration_str = "%.3f" % duration
300306
self._call_attr(ATTR_CLEANUP, *args)
@@ -324,7 +330,9 @@ def run(self):
324330
# summary
325331
# We can do that only on Graalpython
326332
if report_startup:
327-
print("### STARTUP duration: %.3f s" % (startup / 10e9))
333+
print("### STARTUP at iteration: %d, duration: %.3f" % (self.startup[0], startup_ns / 1e9))
334+
print("### EARLY WARMUP at iteration: %d, duration: %.3f" % (self.startup[1], early_warmup_ns / 1e9))
335+
print("### LATE WARMUP at iteration: %d, duration: %.3f" % (self.startup[2], late_warmup_ns / 1e9))
328336
if self._run_once:
329337
print("### SINGLE RUN duration: %.3f s" % durations[0])
330338
else:
@@ -359,7 +367,7 @@ def run_benchmark(args):
359367
warmup = -1
360368
warmup_runs = 0
361369
iterations = 1
362-
startup = False
370+
startup = None
363371
bench_file = None
364372
bench_args = []
365373
paths = []
@@ -385,8 +393,12 @@ def run_benchmark(args):
385393
elif arg.startswith("--warmup-runs"):
386394
warmup_runs = _as_int(arg.split("=")[1])
387395

388-
elif arg == '-s' or arg == '--startup':
389-
startup = True
396+
elif arg.startswith('--startup'):
397+
try:
398+
itrs = arg.split("=")[1].split(",")
399+
startup = (int(itrs[0]), int(itrs[1]), int(itrs[2]))
400+
except:
401+
raise TypeError("incorrect argument; must be in form of '-s 1,10,100'")
390402

391403
elif arg == '-p':
392404
i += 1
@@ -400,6 +412,9 @@ def run_benchmark(args):
400412
bench_args.append(arg)
401413
i += 1
402414

415+
if startup and iterations < max(startup):
416+
print("### WARNING: you've specified less iterations than required to measure the startup")
417+
403418
# set the paths if specified
404419
print(_HRULE)
405420
sys.path.append(os.path.split(bench_file)[0])
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/usr/bin/env python
2+
# Copyright 2008-2010 Isaac Gouy
3+
# Copyright (c) 2013, 2014, Regents of the University of California
4+
# Copyright (c) 2017, 2020, Oracle and/or its affiliates.
5+
# All rights reserved.
6+
#
7+
# Revised BSD license
8+
#
9+
# This is a specific instance of the Open Source Initiative (OSI) BSD license
10+
# template http://www.opensource.org/licenses/bsd-license.php
11+
#
12+
# Redistribution and use in source and binary forms, with or without
13+
# modification, are permitted provided that the following conditions are met:
14+
#
15+
# Redistributions of source code must retain the above copyright notice, this
16+
# list of conditions and the following disclaimer.
17+
#
18+
# Redistributions in binary form must reproduce the above copyright notice,
19+
# this list of conditions and the following disclaimer in the documentation
20+
# and/or other materials provided with the distribution.
21+
#
22+
# Neither the name of "The Computer Language Benchmarks Game" nor the name of
23+
# "The Computer Language Shootout Benchmarks" nor the name "nanobench" nor the
24+
# name "bencher" nor the names of its contributors may be used to endorse or
25+
# promote products derived from this software without specific prior written
26+
# permission.
27+
#
28+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
32+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38+
39+
# The Computer Language Benchmarks Game
40+
# http://shootout.alioth.debian.org/
41+
#
42+
# contributed by Antoine Pitrou
43+
# modified by Dominique Wahli
44+
# modified by Heinrich Acker
45+
46+
47+
def make_tree(item, depth):
48+
if not depth: return item, None, None
49+
item2 = item + item
50+
depth -= 1
51+
return item, make_tree(item2 - 1, depth), make_tree(item2, depth)
52+
53+
54+
def check_tree(xxx_todo_changeme):
55+
(item, left, right) = xxx_todo_changeme
56+
if not left: return item
57+
return item + check_tree(left) - check_tree(right)
58+
59+
60+
def main(num):
61+
min_depth = 4
62+
max_depth = max(min_depth + 2, num)
63+
stretch_depth = max_depth + 1
64+
65+
print("stretch tree of depth %d\t check:" % stretch_depth, check_tree(make_tree(0, stretch_depth)))
66+
67+
long_lived_tree = make_tree(0, max_depth)
68+
69+
iterations = 2**max_depth
70+
71+
for depth in range(min_depth, stretch_depth, 2):
72+
73+
check = 0
74+
for i in range(1, iterations + 1):
75+
check += check_tree(make_tree(i, depth)) + check_tree(make_tree(-i, depth))
76+
77+
print("%d\t trees of depth %d\t check:" % (iterations * 2, depth), check)
78+
iterations //= 4
79+
80+
print("long lived tree of depth %d\t check:" % max_depth, check_tree(long_lived_tree))
81+
82+
83+
def __benchmark__(num=10):
84+
main(num)

0 commit comments

Comments
 (0)