libzahl

big integer library
git clone git://git.suckless.org/libzahl
Log | Files | Refs | README | LICENSE

commit 068fc72f804ef972a35f06b06b049a84db1ce6a7
parent e007b8f8fb388ffeb059fccd91ca28f4faaf1ef3
Author: Mattias Andrée <maandree@kth.se>
Date:   Sun,  1 May 2016 23:21:27 +0200

Benchmarking stuff

Signed-off-by: Mattias Andrée <maandree@kth.se>

Diffstat:
Mbench/benchmark-func.c | 5++++-
Mbench/benchmark.c | 2++
Mbench/benchmark.h | 8++++++--
Abench/merge-benchmark-func.py | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abench/merge-benchmark.py | 33+++++++++++++++++++++++++++++++++
Mbench/plot.py | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
6 files changed, 165 insertions(+), 13 deletions(-)

diff --git a/bench/benchmark-func.c b/bench/benchmark-func.c @@ -150,6 +150,9 @@ gettime(size_t m) X(zswap, FAST2D(FULL), zswap(temp, *a),)\ X(zcmpmag, FAST2D(FULL), zcmpmag(temp2, *a),)\ X(zcmp, FAST2D(FULL), zcmp(temp2, *a),)\ + X(pos_zcmpi, FAST2D(FULL), zcmpi(*a, 1000000000LL),)\ + X(zcmpi, FAST2D(FULL), zcmpi(*a, -1000000000LL),)\ + X(zcmpu, FAST2D(FULL), zcmpu(*a, 1000000000ULL),)\ X(sqr_zmul, SLOW2D(FULL), zmul(temp, *a, temp2),)\ X(zsqr, SLOW2D(FULL), zsqr(temp, *a),)\ X(zstr_length, SLOW2D(FULL), zstr_length(*a, 10),)\ @@ -272,7 +275,7 @@ main(int argc, char *argv[]) return 1; } zsetup(jmp); - printf("%s\n", BIGINT_LIBRARY); + printf("%s%s\n", BIGINT_LIBRARY, LIBRARY_SUFFIX); zinit(temp); zinit(temp2); diff --git a/bench/benchmark.c b/bench/benchmark.c @@ -71,6 +71,7 @@ main(int argc, char *argv[]) BENCHMARK(zcmpmag(a, b), 1); BENCHMARK(zcmp(a, b), 1); BENCHMARK(zcmpi(a, 1000000000LL), 1); + BENCHMARK(zcmpi(a, -1000000000LL), 1); BENCHMARK(zcmpu(a, 1000000000ULL), 1); BENCHMARK(zbset(c, a, 76, 1), 1); BENCHMARK(zbset(a, a, 76, 1), 1); @@ -105,6 +106,7 @@ main(int argc, char *argv[]) BENCHMARK(zstr(a, buf, sizeof(buf) - 1), 0); BENCHMARK(zrand(c, DEFAULT_RANDOM, QUASIUNIFORM, a), 0); BENCHMARK(zrand(c, DEFAULT_RANDOM, UNIFORM, a), 0); + BENCHMARK(zrand(c, DEFAULT_RANDOM, MODUNIFORM, a), 0); BENCHMARK(zptest(d, a, 5), 0); BENCHMARK(zsave(a, buf), 1); BENCHMARK(zload(a, buf), 1); diff --git a/bench/benchmark.h b/bench/benchmark.h @@ -14,12 +14,16 @@ # include BENCHMARK_LIB #else # include "../zahl.h" -# define BIGINT_LIBRARY "libzahl" +# define BIGINT_LIBRARY "libzahl" +#endif + +#ifndef LIBRARY_SUFFIX +# define LIBRARY_SUFFIX "" #endif #ifndef CLOCK_MONOTONIC_RAW -# define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC +# define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC #endif diff --git a/bench/merge-benchmark-func.py b/bench/merge-benchmark-func.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# See LICENSE file for copyright and license details. + + +# Invoke using `env SELECT_MIN=` to select the minimum value, +# rather than concatenate. This applies to 1-dimensional data only. + + +import sys, os + +line_count = None +files = [] + +for path in sys.argv[1:]: + with open(path, 'rb') as file: + data = file.read() + data = data.decode('utf-8', 'strict') + if data[-1] == '\n': + data = data[:-1] + data = data.split('\n') + if line_count is None: + line_count = len(data) + elif len(data) != line_count: + print('%s: line count mismatch' % sys.argv[0], file = sys.stderr) + sys.exit(1) + files.append(data) + +dim = int(files[0][1]) +skip = 1 + dim +for i in range(skip): + print(files[0][i]) + +if dim > 1: + for i in range(skip, line_count): + best_nsec = None + best_line = None + for lines in files: + line = lines[i] + nsec = int(line) + if best_nsec is None or nsec < best_nsec: + best_nsec, best_line = nsec, line + print(best_line) +else 'SELECT_MIN' not in os.environ: + for lines in files: + for i in range(skip, line_count): + print(lines[i]) +else: + best_nsec = None + best_line = None + for lines in files: + for i in range(skip, line_count): + line = lines[i] + nsec = int(line) + if best_nsec is None or nsec < best_nsec: + best_nsec, best_line = nsec, line + print(best_line) diff --git a/bench/merge-benchmark.py b/bench/merge-benchmark.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +# See LICENSE file for copyright and license details. + +import sys + +line_count = None +files = [] + +for path in sys.argv[1:]: + with open(path, 'rb') as file: + data = file.read() + data = data.decode('utf-8', 'strict') + if data[-1] == '\n': + data = data[:-1] + data = data.split('\n') + if line_count is None: + line_count = len(data) + elif len(data) != line_count: + print('%s: line count mismatch' % sys.argv[0], file = sys.stderr) + sys.exit(1) + files.append(data) + +for i in range(line_count): + best_sec = None + best_nsec = None + best_line = None + for lines in files: + line = lines[i] + [sec, nsec] = line.split(':')[1].split(' ')[1].split('.') + [sec, nsec] = [int(sec), int(nsec)] + if best_sec is None or sec < best_sec or (sec == best_sec and nsec < best_nsec): + best_sec, best_nsec, best_line = sec, nsec, line + print(best_line) diff --git a/bench/plot.py b/bench/plot.py @@ -1,4 +1,21 @@ #!/usr/bin/env python3 +# See LICENSE file for copyright and license details. + + +# Invoke using `env XKCD_STYLE=` to for more a comical plot style. + +# Invoke using `env PER_BIT=` to divide all time values by the number +# of bits that where processed. This applies to 2-dimensional data only. + +# Invoke using `env VIOLIN_STYLE=` to draw violin plots rather than +# box plots. This applies to multisample 1-dimensional data only. +# If used, used `env SHOW_MEAN=` will show that mean value in place +# of the median value. + +# For multisample 1-dimensional, if `env VIOLIN_STYLE=` is not used +# `env NOTCH_STYLE=`, `env PATCH_ARTIST`, and `env SHOW_MEAN` may be +# applied. + import sys, os import matplotlib.pyplot as plot @@ -6,11 +23,16 @@ import matplotlib.pyplot as plot xkcdstyle = 'XKCD_STYLE' in os.environ if xkcdstyle: plot.xkcd() -plot.figure() +fig = plot.figure() multiple = 1 smultiple = '' +labels_1d = [] +values_1d = [] + +xint = lambda x : (float(x) if '.' in x else int(x)) + for path in sys.argv[1:]: if path.startswith('*'): multiple = float(path[1:]) @@ -19,18 +41,22 @@ for path in sys.argv[1:]: with open(path, 'rb') as file: lines = file.read() lines = lines.decode('utf-8', 'strict').split('\n') - label, dim, xpoints, values = lines[0], int(lines[1]), lines[2], lines[3:] - label += smultiple - xpoints = [int(x) for x in xpoints.split(' ')] - xpoints[1] += 1 - xpoints = list(range(*xpoints)) - if dim == 3: + label, dim, values = lines[0] + smultiple, int(lines[1]), lines[2:] + if dim > 1: + xpoints, values = values[0], values[1:] + xpoints = [int(x) for x in xpoints.split(' ')] + xpoints[1] += 1 + xpoints = list(range(*xpoints)) + if dim > 2: ypoints, values = values[0], values[1:] ypoints = [int(x) for x in ypoints.split(' ')] ypoints[1] += 1 ypoints = list(range(*ypoints)) - values = [float(v) * multiple for v in values if v != ''] - if dim == 2: + values = [xint(v) * multiple for v in values if v != ''] + if dim == 1: + labels_1d.append(label) + values_1d.append(values) + elif dim == 2: if 'PER_BIT' in os.environ: values = [y / x for y, x in zip(values, xpoints)] plot.plot(xpoints, values, label = label) @@ -39,7 +65,35 @@ for path in sys.argv[1:]: multiple = 1 smultiple = '' -if dim == 2: +if dim == 1: + plot.ylabel('time') + if len(values_1d[0]) == 1: + plot.bar(range(len(values_1d)), + [vs[0] for vs in values_1d], + align = 'center', + orientation = 'vertical', + tick_label = labels_1d) + labels_1d = None + elif 'VIOLIN_STYLE' in os.environ: + plot.violinplot(values_1d, + vert = True, + showmeans = 'SHOW_MEAN' in os.environ, + showmedians = 'SHOW_MEAN' not in os.environ, + showextrema = True) + else: + plot.boxplot(values_1d, + vert = True, + notch = 'NOTCH_STYLE' in os.environ, + patch_artist = 'PATCH_ARTIST' in os.environ) + if 'SHOW_MEAN' in os.environ: + for i in range(len(values_1d)): + mean = sum(values_1d[i]) / len(values_1d[i]) + plot.plot([i + 0.75, i + 1.25], [mean, mean]); + if labels_1d is not None: + plot.setp(fig.axes, + xticks = [x + 1 for x in range(len(values_1d))], + xticklabels = labels_1d) +elif dim == 2: plot.legend(loc = 'best') plot.xlabel('bits') plot.ylabel('time')