diff options
Diffstat (limited to 'doc/Benchmarks.md')
| -rw-r--r-- | doc/Benchmarks.md | 88 |
1 files changed, 57 insertions, 31 deletions
diff --git a/doc/Benchmarks.md b/doc/Benchmarks.md index 4aeb8a4..b173f5c 100644 --- a/doc/Benchmarks.md +++ b/doc/Benchmarks.md @@ -46,68 +46,94 @@ Delorie using the tools from dj/malloc branch of the glibc. 1. Make sure your command is deterministic and allocator behavior is a significant part of your measured results 2. Create a new Python class for your benchmark. You can inherit from the - provided class src.Benchmark + provided class src.Benchmark. 3. Implement your custom functionality -4. Export a object of your class, import and add it to the list of benchmarks in - bench.py +4. Export a object of your class in a python file under src/benchmarks named + like your exported object and allocbench will find it automatically. #### loop.py as Example ```python +# Copyright 2018-2019 Florian Fischer <florian.fl.fischer@fau.de> +# +# This file is part of allocbench. +# +# allocbench is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# allocbench is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with allocbench. If not, see <http://www.gnu.org/licenses/>. + +"""Definition of the loop micro benchmark""" + from src.benchmark import Benchmark +NAME = "loop" -class Benchmark_Loop(Benchmark): - def __init__(self): - self.name = "loop" - self.descrition = """This benchmark makes n allocations in t concurrent - threads. Each iteration one block is allocated, """, +CMD = "loop{binary_suffix} {nthreads} 1000000 {maxsize}" + +ARGS = {"maxsize": [2 ** x for x in range(6, 16)], + "nthreads": Benchmark.scale_threads_for_cpus(2)} - self.cmd = "loop{binary_suffix} {nthreads} 1000000 {maxsize}" +class BenchmarkLoop(Benchmark): + """Loop micro benchmark - self.args = { - "maxsize": [2 ** x for x in range(6, 16)], - "nthreads": Benchmark.scale_threads_for_cpus(2) - } + This benchmark allocates and frees n blocks in t concurrent threads. + """ + def __init__(self): self.requirements = ["loop"] - super().__init__() + super().__init__(NAME, CMD, ARGS) def summary(self): # Speed - self.plot_fixed_arg("perm.nthreads / (float({task-clock})/1000)", + self.plot_fixed_arg("perm.nthreads / ({task-clock}/1000)", ylabel='"MOPS/cpu-second"', title='"Loop: " + arg + " " + str(arg_value)', - filepostfix="time") + filepostfix="time", + autoticks=False) - # Memusage - self.plot_fixed_arg("int({VmHWM})", - ylabel='"VmHWM in kB"', - title='"Loop Memusage: " + arg + " " + str(arg_value)', - filepostfix="memusage") + scale = list(self.results["allocators"].keys())[0] + self.plot_fixed_arg("perm.nthreads / ({task-clock}/1000)", + ylabel='"MOPS/cpu-second normalized {}"'.format(scale), + title=f'"Loop: " + arg + " " + str(arg_value) + " normalized {scale}"', + filepostfix="time.norm", + scale=scale, + autoticks=False) # L1 cache misses self.plot_fixed_arg("({L1-dcache-load-misses}/{L1-dcache-loads})*100", ylabel='"L1 misses in %"', title='"Loop l1 cache misses: " + arg + " " + str(arg_value)', - filepostfix="l1misses") + filepostfix="l1misses", + autoticks=False) # Speed Matrix - self.write_best_doublearg_tex_table("perm.nthreads / (float({task-clock})/1000)", - filepostfix="memusage.matrix") + self.write_best_doublearg_tex_table("perm.nthreads / ({task-clock}/1000)", + filepostfix="time.matrix") + + self.export_stats_to_csv("task-clock") + self.export_stats_to_dataref("task-clock") -loop = Benchmark_Loop() +loop = BenchmarkLoop() ``` ## The Benchmark class -The class Benchmark defined in the src/benchmark.py implements lots of +The class Benchmark defined in the src/benchmark.py implements most common operations for a benchmark. It provides load and save functions using pythons pickle module, helpers generating plots using matplotlib and most importantly a run method using the attributes `cmd` and `args` to execute your benchmark. To not enforce some -result format hooks are available to parse the results of your benchmark yourself. +output format hooks are available to parse the output of your benchmark yourself. ### run @@ -117,7 +143,7 @@ for number_of_runs preallocator_hook for each permutation of args - build command + buildup command run command process_output @@ -127,16 +153,16 @@ for number_of_runs #### run hooks -* `preallocator_hook((alloc_name, alloc_definition), current_run, environment, verbose)` is called +* `preallocator_hook((alloc_name, alloc_definition), current_run, environment)` is called if available once per allocator before any command is executed. This hook may be useful if you want to prepare stuff for each allocator. The mysql benchmark uses this hook to start the mysql server with the current allocator. -* `process_output(result_dict, stdout, stderr, allocator_name, permutation, verbose)` +* `process_output(result_dict, stdout, stderr, allocator_name, permutation)` is called after each run of your command. Store relevant data in result_dict to use it for your summary. -* `postallocator_hook((alloc_name, alloc_definition), current_run, verbose)` +* `postallocator_hook((alloc_name, alloc_definition), current_run)` is called after all permutations are done for the current allocator. The mysql benchmark uses this hook to terminate the in preallocator_hook started mysql server. |
