This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch master updated. glibc-2.25-556-g25d5247
- From: siddhesh at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 22 Jun 2017 18:16:43 -0000
- Subject: GNU C Library master sources branch master updated. glibc-2.25-556-g25d5247
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".
The branch, master has been updated
via 25d5247277760e669a69618ce99ce6065e92362c (commit)
via 5ee1e3cebc47495a36d17a0066c241978ca6f502 (commit)
via 738a9914a066a31750925543a8c6d2661bd61345 (commit)
from 5070551cbf0ba8f69e15e1a19f8989b812b6a651 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=25d5247277760e669a69618ce99ce6065e92362c
commit 25d5247277760e669a69618ce99ce6065e92362c
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Thu Jun 22 23:44:50 2017 +0530
benchtests: New script to parse memcpy results
Read the memcpy results in json and print out the results in tabular
form, in addition to generating a graph of the results to compare all
of the implementations.
The format of the output is extensible enough to allow this kind of
analysis to be done on other string functions as well.
* benchtests/scripts/benchout_strings.schema.json: New file.
* benchtests/scripts/compare_strings.py: New file.
diff --git a/benchtests/scripts/benchout_strings.schema.json b/benchtests/scripts/benchout_strings.schema.json
new file mode 100644
index 0000000..7c9a671
--- /dev/null
+++ b/benchtests/scripts/benchout_strings.schema.json
@@ -0,0 +1,44 @@
+{
+ "title": "string benchmark",
+ "type": "object",
+ "properties": {
+ "timing_type": {
+ "type": "string"
+ },
+ "functions": {
+ "title": "Associative array of functions",
+ "type": "object",
+ "patternProperties": {
+ "^[_a-zA-Z][_a-zA-Z0-9]+$": {
+ "title": "Function names",
+ "type": "object",
+ "properties": {
+ "bench-variant": {"type": "string"},
+ "ifuncs": {
+ "type": "array",
+ "items": {"type": "string"}
+ },
+ "results": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "timings": {
+ "type": "array",
+ "items": {"type": "number"}
+ }
+ },
+ "additionalProperties": {"type": "number"},
+ "minProperties": 2
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "minProperties": 1
+ }
+ },
+ "required": ["timing_type", "functions"],
+ "additionalProperties": false
+}
diff --git a/benchtests/scripts/compare_strings.py b/benchtests/scripts/compare_strings.py
new file mode 100755
index 0000000..9d73ec4
--- /dev/null
+++ b/benchtests/scripts/compare_strings.py
@@ -0,0 +1,129 @@
+#!/usr/bin/python
+# Copyright (C) 2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+"""Compare results of string functions
+
+Given a string benchmark result file, print a table with comparisons with a
+baseline. The baseline is the first function, which typically is the builtin
+function.
+"""
+import sys
+import os
+import json
+import pylab
+
+try:
+ import jsonschema as validator
+except ImportError:
+ print('Could not find jsonschema module.')
+ raise
+
+
+def parse_file(filename, schema_filename):
+ with open(schema_filename, 'r') as schemafile:
+ schema = json.load(schemafile)
+ with open(filename, 'r') as benchfile:
+ bench = json.load(benchfile)
+ validator.validate(bench, schema)
+ return bench
+
+
+def draw_graph(f, v, ifuncs, results):
+ """Plot graphs for functions
+
+ Plot line graphs for each of the ifuncs
+
+ Args:
+ f: Function name
+ v: Benchmark variant for the function.
+ ifuncs: List of ifunc names
+ results: Dictionary of results for each test criterion
+ """
+ xkeys = results.keys()
+
+ pylab.clf()
+ fig = pylab.figure(frameon=False)
+ fig.set_size_inches(32, 18)
+ pylab.ylabel('Performance improvement from base')
+ X = range(len(xkeys))
+ pylab.xticks(X, xkeys)
+
+ i = 0
+
+ while i < len(ifuncs):
+ Y = [results[k][i] for k in xkeys]
+ lines = pylab.plot(X, Y, label=':'+ifuncs[i])
+ i = i + 1
+
+ pylab.legend()
+ pylab.grid()
+ pylab.savefig('%s-%s.png' % (f, v), bbox_inches='tight')
+
+
+def process_results(results, attrs):
+ """ Process results and print them
+
+ Args:
+ results: JSON dictionary of results
+ attrs: Attributes that form the test criteria
+ """
+
+ for f in results['functions'].keys():
+ print('Function: %s' % f)
+ print('\t'.join(results['functions'][f]['ifuncs']))
+ v = results['functions'][f]['bench-variant']
+ print('Variant: %s' % v)
+ print("=" * 80)
+ graph_res = {}
+ for res in results['functions'][f]['results']:
+ attr_list = ['%s=%s' % (a, res[a]) for a in attrs]
+ first = True
+ key = ','.join(attr_list)
+ sys.stdout.write('%s: \t' % key)
+ graph_res[key] = res['timings']
+ for t in res['timings']:
+ sys.stdout.write ('%.2f' % t)
+ if first:
+ first = False
+ else:
+ diff = (res['timings'][0] - t) * 100 / res['timings'][0]
+
+ sys.stdout.write (' (%.2f%%)' % diff)
+ sys.stdout.write('\t')
+ print('')
+ draw_graph(f, v, results['functions'][f]['ifuncs'], graph_res)
+
+
+def main(args):
+ """Program Entry Point
+
+ Take a string benchmark output file and compare timings.
+ """
+ if len(args) < 3:
+ print('Usage: %s <input file> <schema file> attr1 [attr2 ...]' % sys.argv[0])
+ sys.exit(os.EX_USAGE)
+
+ filename = args[0]
+ schema_filename = args[1]
+ attrs = args[2:]
+
+ results = parse_file(filename, schema_filename)
+ process_results(results, attrs)
+
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=5ee1e3cebc47495a36d17a0066c241978ca6f502
commit 5ee1e3cebc47495a36d17a0066c241978ca6f502
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Thu Jun 22 23:44:19 2017 +0530
benchtests: Make memcpy benchmarks print results in json
Print the benchmark output for various memcpy benchmarks in json so
that it can be predictably parsed and analyzed.
* benchtests/bench-memcpy-large.c: Include json-lib.h.
(do_one_test): Print json.
(do_test): Likewise.
(test_main): Likewise.
* benchtests/bench-memcpy-random.c: Include json-lib.h.
(do_one_test): Print json.
(do_test): Likewise.
(test_main): Likewise.
* benchtests/bench-memcpy.c: Include json-lib.h.
(do_one_test): Print json.
(do_test): Likewise.
(test_main): Likewise.
diff --git a/benchtests/bench-memcpy-large.c b/benchtests/bench-memcpy-large.c
index f50674e..ae5e819 100644
--- a/benchtests/bench-memcpy-large.c
+++ b/benchtests/bench-memcpy-large.c
@@ -28,10 +28,12 @@
IMPL (memcpy, 1)
#endif
+#include "json-lib.h"
+
typedef char *(*proto_t) (char *, const char *, size_t);
static void
-do_one_test (impl_t *impl, char *dst, const char *src,
+do_one_test (json_ctx_t *json_ctx, impl_t *impl, char *dst, const char *src,
size_t len)
{
size_t i, iters = 16;
@@ -66,11 +68,11 @@ do_one_test (impl_t *impl, char *dst, const char *src,
TIMING_DIFF (cur, start, stop);
- TIMING_PRINT_MEAN ((double) cur, (double) iters);
+ json_element_double (json_ctx, (double) cur / (double) iters);
}
static void
-do_test (size_t align1, size_t align2, size_t len)
+do_test (json_ctx_t *json_ctx, size_t align1, size_t align2, size_t len)
{
size_t i, j;
char *s1, *s2;
@@ -89,34 +91,55 @@ do_test (size_t align1, size_t align2, size_t len)
for (i = 0, j = 1; i < len; i++, j += 23)
s1[i] = j;
- printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
+ json_element_object_begin (json_ctx);
+ json_attr_uint (json_ctx, "length", (double) len);
+ json_attr_uint (json_ctx, "align1", (double) align1);
+ json_attr_uint (json_ctx, "align2", (double) align2);
+ json_array_begin (json_ctx, "timings");
FOR_EACH_IMPL (impl, 0)
- do_one_test (impl, s2, s1, len);
+ do_one_test (json_ctx, impl, s2, s1, len);
- putchar ('\n');
+ json_array_end (json_ctx);
+ json_element_object_end (json_ctx);
}
int
test_main (void)
{
+ json_ctx_t json_ctx;
size_t i;
test_init ();
- printf ("%23s", "");
+ json_init (&json_ctx, 0, stdout);
+
+ json_document_begin (&json_ctx);
+ json_attr_string (&json_ctx, "timing_type", TIMING_TYPE);
+
+ json_attr_object_begin (&json_ctx, "functions");
+ json_attr_object_begin (&json_ctx, "memcpy");
+ json_attr_string (&json_ctx, "bench-variant", "large");
+
+ json_array_begin (&json_ctx, "ifuncs");
FOR_EACH_IMPL (impl, 0)
- printf ("\t%s", impl->name);
- putchar ('\n');
+ json_element_string (&json_ctx, impl->name);
+ json_array_end (&json_ctx);
+ json_array_begin (&json_ctx, "results");
for (i = START_SIZE; i <= MIN_PAGE_SIZE; i <<= 1)
{
- do_test (0, 0, i + 7);
- do_test (0, 3, i + 15);
- do_test (3, 0, i + 31);
- do_test (3, 5, i + 63);
+ do_test (&json_ctx, 0, 0, i + 7);
+ do_test (&json_ctx, 0, 3, i + 15);
+ do_test (&json_ctx, 3, 0, i + 31);
+ do_test (&json_ctx, 3, 5, i + 63);
}
+ json_array_end (&json_ctx);
+ json_attr_object_end (&json_ctx);
+ json_attr_object_end (&json_ctx);
+ json_document_end (&json_ctx);
+
return ret;
}
diff --git a/benchtests/bench-memcpy-random.c b/benchtests/bench-memcpy-random.c
index 9ae925e..9c7cc2b 100644
--- a/benchtests/bench-memcpy-random.c
+++ b/benchtests/bench-memcpy-random.c
@@ -21,6 +21,7 @@
#define TEST_NAME "memcpy"
#include "bench-string.h"
#include <assert.h>
+#include "json-lib.h"
IMPL (memcpy, 1)
@@ -96,7 +97,8 @@ init_copy_distribution (void)
static void
-do_one_test (impl_t *impl, char *dst, char *src, copy_t *copy, size_t n)
+do_one_test (json_ctx_t *json_ctx, impl_t *impl, char *dst, char *src,
+ copy_t *copy, size_t n)
{
timing_t start, stop, cur;
size_t iters = INNER_LOOP_ITERS * 20;
@@ -109,11 +111,11 @@ do_one_test (impl_t *impl, char *dst, char *src, copy_t *copy, size_t n)
TIMING_DIFF (cur, start, stop);
- TIMING_PRINT_MEAN ((double) cur, (double) iters);
+ json_element_double (json_ctx, (double) cur / (double) iters);
}
static void
-do_test (size_t max_size)
+do_test (json_ctx_t *json_ctx, size_t max_size)
{
for (int i = 0; i < max_size; i++)
buf1[i] = i * 3;
@@ -129,27 +131,47 @@ do_test (size_t max_size)
copy[i].len = size_arr[rand () & SIZE_MASK];
}
- printf ("Memory size %6zd:", max_size);
+ json_element_object_begin (json_ctx);
+ json_attr_uint (json_ctx, "max-size", (double) max_size);
+ json_array_begin (json_ctx, "timings");
FOR_EACH_IMPL (impl, 0)
- do_one_test (impl, (char *) buf2, (char *) buf1, copy, NUM_COPIES);
+ do_one_test (json_ctx, impl, (char *) buf2, (char *) buf1, copy, NUM_COPIES);
- putchar ('\n');
+ json_array_end (json_ctx);
+ json_element_object_end (json_ctx);
}
int
test_main (void)
{
+ json_ctx_t json_ctx;
+
test_init ();
init_copy_distribution ();
- printf ("%23s", "");
+ json_init (&json_ctx, 0, stdout);
+
+ json_document_begin (&json_ctx);
+ json_attr_string (&json_ctx, "timing_type", TIMING_TYPE);
+
+ json_attr_object_begin (&json_ctx, "functions");
+ json_attr_object_begin (&json_ctx, "memcpy");
+ json_attr_string (&json_ctx, "bench-variant", "random");
+
+ json_array_begin (&json_ctx, "ifuncs");
FOR_EACH_IMPL (impl, 0)
- printf ("\t%s", impl->name);
- putchar ('\n');
+ json_element_string (&json_ctx, impl->name);
+ json_array_end (&json_ctx);
+ json_array_begin (&json_ctx, "results");
for (int i = 4; i <= 64; i = i * 2)
- do_test (i * 1024);
+ do_test (&json_ctx, i * 1024);
+
+ json_array_end (&json_ctx);
+ json_attr_object_end (&json_ctx);
+ json_attr_object_end (&json_ctx);
+ json_document_end (&json_ctx);
return ret;
}
diff --git a/benchtests/bench-memcpy.c b/benchtests/bench-memcpy.c
index 6d0b9fb..92ecc64 100644
--- a/benchtests/bench-memcpy.c
+++ b/benchtests/bench-memcpy.c
@@ -46,10 +46,12 @@ builtin_memcpy (char *dst, const char *src, size_t n)
}
#endif
+# include "json-lib.h"
+
typedef char *(*proto_t) (char *, const char *, size_t);
static void
-do_one_test (impl_t *impl, char *dst, const char *src,
+do_one_test (json_ctx_t *json_ctx, impl_t *impl, char *dst, const char *src,
size_t len)
{
size_t i, iters = INNER_LOOP_ITERS;
@@ -84,11 +86,11 @@ do_one_test (impl_t *impl, char *dst, const char *src,
TIMING_DIFF (cur, start, stop);
- TIMING_PRINT_MEAN ((double) cur, (double) iters);
+ json_element_double (json_ctx, (double) cur / (double) iters);
}
static void
-do_test (size_t align1, size_t align2, size_t len)
+do_test (json_ctx_t *json_ctx, size_t align1, size_t align2, size_t len)
{
size_t i, j;
char *s1, *s2;
@@ -107,61 +109,82 @@ do_test (size_t align1, size_t align2, size_t len)
for (i = 0, j = 1; i < len; i++, j += 23)
s1[i] = j;
- printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
+ json_element_object_begin (json_ctx);
+ json_attr_uint (json_ctx, "length", (double) len);
+ json_attr_uint (json_ctx, "align1", (double) align1);
+ json_attr_uint (json_ctx, "align2", (double) align2);
+ json_array_begin (json_ctx, "timings");
FOR_EACH_IMPL (impl, 0)
- do_one_test (impl, s2, s1, len);
+ do_one_test (json_ctx, impl, s2, s1, len);
- putchar ('\n');
+ json_array_end (json_ctx);
+ json_element_object_end (json_ctx);
}
int
test_main (void)
{
+ json_ctx_t json_ctx;
size_t i;
test_init ();
- printf ("%23s", "");
+ json_init (&json_ctx, 0, stdout);
+
+ json_document_begin (&json_ctx);
+ json_attr_string (&json_ctx, "timing_type", TIMING_TYPE);
+
+ json_attr_object_begin (&json_ctx, "functions");
+ json_attr_object_begin (&json_ctx, "memcpy");
+ json_attr_string (&json_ctx, "bench-variant", "default");
+
+ json_array_begin (&json_ctx, "ifuncs");
FOR_EACH_IMPL (impl, 0)
- printf ("\t%s", impl->name);
- putchar ('\n');
+ json_element_string (&json_ctx, impl->name);
+ json_array_end (&json_ctx);
+ json_array_begin (&json_ctx, "results");
for (i = 0; i < 18; ++i)
{
- do_test (0, 0, 1 << i);
- do_test (i, 0, 1 << i);
- do_test (0, i, 1 << i);
- do_test (i, i, 1 << i);
+ do_test (&json_ctx, 0, 0, 1 << i);
+ do_test (&json_ctx, i, 0, 1 << i);
+ do_test (&json_ctx, 0, i, 1 << i);
+ do_test (&json_ctx, i, i, 1 << i);
}
for (i = 0; i < 32; ++i)
{
- do_test (0, 0, i);
- do_test (i, 0, i);
- do_test (0, i, i);
- do_test (i, i, i);
+ do_test (&json_ctx, 0, 0, i);
+ do_test (&json_ctx, i, 0, i);
+ do_test (&json_ctx, 0, i, i);
+ do_test (&json_ctx, i, i, i);
}
for (i = 3; i < 32; ++i)
{
if ((i & (i - 1)) == 0)
continue;
- do_test (0, 0, 16 * i);
- do_test (i, 0, 16 * i);
- do_test (0, i, 16 * i);
- do_test (i, i, 16 * i);
+ do_test (&json_ctx, 0, 0, 16 * i);
+ do_test (&json_ctx, i, 0, 16 * i);
+ do_test (&json_ctx, 0, i, 16 * i);
+ do_test (&json_ctx, i, i, 16 * i);
}
for (i = 32; i < 64; ++i)
{
- do_test (0, 0, 32 * i);
- do_test (i, 0, 32 * i);
- do_test (0, i, 32 * i);
- do_test (i, i, 32 * i);
+ do_test (&json_ctx, 0, 0, 32 * i);
+ do_test (&json_ctx, i, 0, 32 * i);
+ do_test (&json_ctx, 0, i, 32 * i);
+ do_test (&json_ctx, i, i, 32 * i);
}
- do_test (0, 0, getpagesize ());
+ do_test (&json_ctx, 0, 0, getpagesize ());
+
+ json_array_end (&json_ctx);
+ json_attr_object_end (&json_ctx);
+ json_attr_object_end (&json_ctx);
+ json_document_end (&json_ctx);
return ret;
}
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=738a9914a066a31750925543a8c6d2661bd61345
commit 738a9914a066a31750925543a8c6d2661bd61345
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Thu Jun 22 23:44:12 2017 +0530
benchtests: Print string array elements, int and uint in json
Enhance the json module in benchtests to print signed and unsigned
integers and string array elements.
* benchtests/json-lib.h: Include inttypes.h.
(json_attr_int, json_attr_int, json_element_string,
json_element_int, json_element_uint): New functions.
* benchtests/json-lib.c: (json_attr_int, json_attr_int,
json_element_string, json_element_int, json_element_uint): New
functions.
diff --git a/benchtests/json-lib.c b/benchtests/json-lib.c
index 61573c5..9743506 100644
--- a/benchtests/json-lib.c
+++ b/benchtests/json-lib.c
@@ -101,6 +101,32 @@ json_attr_string (json_ctx_t *ctx, const char *name, const char *s)
}
void
+json_attr_uint (json_ctx_t *ctx, const char *name, uint64_t d)
+{
+ if (!ctx->first_element)
+ fprintf (ctx->fp, ",\n");
+ else
+ ctx->first_element = false;
+
+ do_indent (ctx);
+
+ fprintf (ctx->fp, "\"%s\": %" PRIu64 , name, d);
+}
+
+void
+json_attr_int (json_ctx_t *ctx, const char *name, int64_t d)
+{
+ if (!ctx->first_element)
+ fprintf (ctx->fp, ",\n");
+ else
+ ctx->first_element = false;
+
+ do_indent (ctx);
+
+ fprintf (ctx->fp, "\"%s\": %" PRId64 , name, d);
+}
+
+void
json_attr_double (json_ctx_t *ctx, const char *name, double d)
{
if (!ctx->first_element)
@@ -137,6 +163,42 @@ json_array_end (json_ctx_t *ctx)
}
void
+json_element_string (json_ctx_t *ctx, const char *s)
+{
+ if (!ctx->first_element)
+ fprintf (ctx->fp, ", \"%s\"", s);
+ else
+ {
+ fprintf (ctx->fp, "\"%s\"", s);
+ ctx->first_element = false;
+ }
+}
+
+void
+json_element_uint (json_ctx_t *ctx, uint64_t d)
+{
+ if (!ctx->first_element)
+ fprintf (ctx->fp, ", %" PRIu64, d);
+ else
+ {
+ fprintf (ctx->fp, "%" PRIu64, d);
+ ctx->first_element = false;
+ }
+}
+
+void
+json_element_int (json_ctx_t *ctx, int64_t d)
+{
+ if (!ctx->first_element)
+ fprintf (ctx->fp, ", %" PRId64, d);
+ else
+ {
+ fprintf (ctx->fp, "%" PRId64, d);
+ ctx->first_element = false;
+ }
+}
+
+void
json_element_double (json_ctx_t *ctx, double d)
{
if (!ctx->first_element)
diff --git a/benchtests/json-lib.h b/benchtests/json-lib.h
index 8a4e591..b3df4b5 100644
--- a/benchtests/json-lib.h
+++ b/benchtests/json-lib.h
@@ -20,6 +20,7 @@
#define __JSON_LIB_H__
#include <stdbool.h>
+#include <inttypes.h>
#include <stdio.h>
struct json_ctx
@@ -37,9 +38,14 @@ void json_document_end (json_ctx_t *ctx);
void json_attr_object_begin (json_ctx_t *ctx, const char *name);
void json_attr_object_end (json_ctx_t *ctx);
void json_attr_string (json_ctx_t *ctx, const char *name, const char *s);
+void json_attr_int (json_ctx_t *ctx, const char *name, int64_t d);
+void json_attr_uint (json_ctx_t *ctx, const char *name, uint64_t d);
void json_attr_double (json_ctx_t *ctx, const char *name, double d);
void json_array_begin (json_ctx_t *ctx, const char *name);
void json_array_end (json_ctx_t *ctx);
+void json_element_string (json_ctx_t *ctx, const char *s);
+void json_element_int (json_ctx_t *ctx, int64_t d);
+void json_element_uint (json_ctx_t *ctx, uint64_t d);
void json_element_double (json_ctx_t *ctx, double d);
void json_element_object_begin (json_ctx_t *ctx);
void json_element_object_end (json_ctx_t *ctx);
-----------------------------------------------------------------------
Summary of changes:
benchtests/bench-memcpy-large.c | 49 +++++++---
benchtests/bench-memcpy-random.c | 42 ++++++--
benchtests/bench-memcpy.c | 75 +++++++++-----
benchtests/json-lib.c | 62 +++++++++++
benchtests/json-lib.h | 6 +
benchtests/scripts/benchout_strings.schema.json | 44 ++++++++
benchtests/scripts/compare_strings.py | 129 +++++++++++++++++++++++
7 files changed, 358 insertions(+), 49 deletions(-)
create mode 100644 benchtests/scripts/benchout_strings.schema.json
create mode 100755 benchtests/scripts/compare_strings.py
hooks/post-receive
--
GNU C Library master sources