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.
This commit is contained in:
Siddhesh Poyarekar 2017-06-22 23:44:50 +05:30
parent 5ee1e3cebc
commit 25d5247277
2 changed files with 173 additions and 0 deletions

View File

@ -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
}

View File

@ -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:])