blob: 5934a0ebd532dfaf94a5506490e41c282e3abe5f [file] [log] [blame]
Jamie Madilld6dfe672015-11-20 12:18:12 -05001#!/usr/bin/python
2#
3# Copyright 2015 The ANGLE Project Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6#
7# perf_test_runner.py:
8# Helper script for running and analyzing perftest results. Runs the
9# tests in an infinite batch, printing out the mean and standard
10# deviation of the population continuously.
11#
12
13import subprocess
14import sys
15import os
Olli Etuahod39f8932015-12-17 17:10:02 +020016import re
17
18base_path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
Jamie Madilld6dfe672015-11-20 12:18:12 -050019
20# You might have to re-order these to find the specific version you want.
Olli Etuahod39f8932015-12-17 17:10:02 +020021perftests_paths = [
22 os.path.join('out', 'Release'),
23 os.path.join('build', 'Release_x64'),
24 os.path.join('build', 'Release_Win32')
25]
Jamie Madilld6dfe672015-11-20 12:18:12 -050026metric = 'score'
27
28scores = []
29
30# Danke to http://stackoverflow.com/a/27758326
31def mean(data):
32 """Return the sample arithmetic mean of data."""
33 n = len(data)
34 if n < 1:
35 raise ValueError('mean requires at least one data point')
36 return float(sum(data))/float(n) # in Python 2 use sum(data)/float(n)
37
38def _ss(data):
39 """Return sum of square deviations of sequence data."""
40 c = mean(data)
41 ss = sum((float(x)-c)**2 for x in data)
42 return ss
43
44def pstdev(data):
45 """Calculates the population standard deviation."""
46 n = len(data)
47 if n < 2:
48 raise ValueError('variance requires at least two data points')
49 ss = _ss(data)
50 pvar = ss/n # the population variance
51 return pvar**0.5
52
53def truncated_list(data, n):
54 """Compute a truncated list, n is truncation size"""
55 if len(data) < n * 2:
56 raise ValueError('list not large enough to truncate')
57 return sorted(data)[n:-n]
58
59def truncated_mean(data, n):
60 return mean(truncated_list(data, n))
61
62def truncated_stddev(data, n):
63 return pstdev(truncated_list(data, n))
64
65perftests_path = ""
66
67# TODO(jmadill): Linux binaries
68for path in perftests_paths:
Olli Etuahod39f8932015-12-17 17:10:02 +020069 perftests_path = os.path.join(base_path, path, 'angle_perftests.exe')
Jamie Madilld6dfe672015-11-20 12:18:12 -050070 if os.path.exists(perftests_path):
71 break
72
73if not os.path.exists(perftests_path):
74 print("Cannot find angle_perftests.exe!")
75 sys.exit(1)
76
77test_name = "DrawCallPerfBenchmark.Run/d3d11_null"
78
79if len(sys.argv) >= 2:
80 test_name = sys.argv[1]
81
Olli Etuaho967cb3b2015-12-17 18:37:16 +020082print('Using test executable: ' + perftests_path)
83print('Test name: ' + test_name)
84
Jamie Madilld6dfe672015-11-20 12:18:12 -050085# Infinite loop of running the tests.
86while True:
87 output = subprocess.check_output([perftests_path, '--gtest_filter=' + test_name])
88
89 start_index = output.find(metric + "=")
90 if start_index == -1:
Olli Etuahod39f8932015-12-17 17:10:02 +020091 print("Did not find the score of the specified test in output:")
92 print(output)
Jamie Madilld6dfe672015-11-20 12:18:12 -050093 sys.exit(1)
94
95 start_index += len(metric) + 2
96
97 end_index = output[start_index:].find(" ")
98 if end_index == -1:
Olli Etuahod39f8932015-12-17 17:10:02 +020099 print("Error parsing output:")
100 print(output)
Jamie Madilld6dfe672015-11-20 12:18:12 -0500101 sys.exit(2)
102
Olli Etuahod39f8932015-12-17 17:10:02 +0200103 m = re.search('Running (\d+) tests', output)
104 if m and int(m.group(1)) > 1:
105 print("Found more than one test result in output:")
106 print(output)
107 sys.exit(3)
108
Jamie Madilld6dfe672015-11-20 12:18:12 -0500109 end_index += start_index
110
111 score = int(output[start_index:end_index])
112 sys.stdout.write("score: " + str(score))
113
114 scores.append(score)
115 sys.stdout.write(", mean: " + str(mean(scores)))
116
117 if (len(scores) > 1):
118 sys.stdout.write(", stddev: " + str(pstdev(scores)))
119
120 if (len(scores) > 7):
121 trucation_n = len(scores) >> 3
122 sys.stdout.write(", truncated mean: " + str(truncated_mean(scores, trucation_n)))
123 sys.stdout.write(", stddev: " + str(truncated_stddev(scores, trucation_n)))
124
125 print("")