Skip to content

Commit 638f4f8

Browse files
committed
[benchmark] Recommended runtime should be < 1ms
* Lowered the threshold for healthy benchmark runtime to be under 1000 μs. * Offer suitable divisor that is power of 10, in addition to the one that’s power of 2. * Expanded the motivation in the docstring.
1 parent d9a89ff commit 638f4f8

File tree

2 files changed

+28
-18
lines changed

2 files changed

+28
-18
lines changed

benchmark/scripts/Benchmark_Driver

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -347,15 +347,20 @@ class BenchmarkDoctor(object):
347347
for correction in [(setup / i) for i in [1, 2]]
348348
] for result in i_series])
349349

350-
if 2500 < runtime:
351-
log = (BenchmarkDoctor.log_runtime.warning if runtime < 500000 else
350+
threshold = 1000
351+
if threshold < runtime:
352+
log = (BenchmarkDoctor.log_runtime.warning if runtime < 10000 else
352353
BenchmarkDoctor.log_runtime.error)
353354
caveat = '' if setup == 0 else ' (excluding the setup overhead)'
354355
log("'%s' execution took at least %d μs%s.", name, runtime, caveat)
355-
factor = int(pow(2, math.ceil(math.log(runtime / 2500.0, 2))))
356+
357+
def factor(base): # suitable divisior that's integer power of base
358+
return int(pow(base, math.ceil(
359+
math.log(runtime / float(threshold), base))))
360+
356361
BenchmarkDoctor.log_runtime.info(
357-
"Decrease the workload of '%s' by a factor of %d, "
358-
"to be less than 2500 μs.", name, factor)
362+
"Decrease the workload of '%s' by a factor of %d (%d), to be "
363+
"less than %d μs.", name, factor(2), factor(10), threshold)
359364

360365
@staticmethod
361366
def _setup_overhead(measurements):

benchmark/scripts/test_Benchmark_Driver.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -548,13 +548,18 @@ def test_benchmark_name_is_at_most_40_chars_long(self):
548548
self.logs['info'])
549549

550550
def test_benchmark_runtime_range(self):
551-
"""Optimized benchmark should run in less then 2500 μs.
552-
553-
With runtimes less than 2500 μs there is better than 1:4 chance of
554-
being interrupted in the middle of measurement due to elapsed 10 ms
555-
quantum used by macos scheduler.
556-
557-
Warn about longer runtime. Runtimes over half a second are an error.
551+
"""Optimized benchmark should run in less then 1000 μs.
552+
553+
Even on calm machine, benchmark with runtime of 2500 μs has 1:4 chance
554+
of being interrupted in the middle of measurement due to elapsed 10 ms
555+
quantum used by macos scheduler. Linux scheduler's quantum is 6ms.
556+
Driver yielding the process before the 10ms quantum elapses helped
557+
a lot, but benchmarks with runtimes under 1ms usually exhibit a strong
558+
mode which is best for accurate performance charaterization.
559+
To minimize the number of involuntary context switches that corrupt our
560+
measurements, we should strive to stay in the microbenchmark range.
561+
562+
Warn about longer runtime. Runtimes over 10ms are an error.
558563
"""
559564
def measurements(name, runtime):
560565
return {'name': name,
@@ -564,7 +569,7 @@ def measurements(name, runtime):
564569
with captured_output() as (out, _):
565570
doctor = BenchmarkDoctor(self.args, BenchmarkDriverMock([]))
566571
doctor.analyze(measurements('Cheetah', 200))
567-
doctor.analyze(measurements('Hare', 2501))
572+
doctor.analyze(measurements('Hare', 1001))
568573
doctor.analyze(measurements('Tortoise', 500000))
569574
doctor.analyze({'name': 'OverheadTurtle',
570575
'OverheadTurtle O i1a': _PTR(min=800000),
@@ -573,17 +578,17 @@ def measurements(name, runtime):
573578

574579
self.assertIn('runtime: ', output)
575580
self.assertNotIn('Cheetah', output)
576-
self.assert_contains(["'Hare' execution took at least 2501 μs."],
581+
self.assert_contains(["'Hare' execution took at least 1001 μs."],
577582
self.logs['warning'])
578583
self.assert_contains(
579-
["Decrease the workload of 'Hare' by a factor of 2, "
580-
"to be less than 2500 μs."], self.logs['info'])
584+
["Decrease the workload of 'Hare' by a factor of 2 (10), "
585+
"to be less than 1000 μs."], self.logs['info'])
581586
self.assert_contains(
582587
["'Tortoise' execution took at least 500000 μs."],
583588
self.logs['error'])
584589
self.assert_contains(
585-
["Decrease the workload of 'Tortoise' by a factor of 256, "
586-
"to be less than 2500 μs."], self.logs['info'])
590+
["Decrease the workload of 'Tortoise' by a factor of 512 (1000), "
591+
"to be less than 1000 μs."], self.logs['info'])
587592
self.assert_contains(
588593
["'OverheadTurtle' execution took at least 600000 μs"
589594
" (excluding the setup overhead)."],

0 commit comments

Comments
 (0)