Ian Romanick | 63b2e42 | 2004-05-26 16:38:38 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python2 |
| 2 | |
| 3 | # (C) Copyright IBM Corporation 2004 |
| 4 | # All Rights Reserved. |
| 5 | # |
| 6 | # Permission is hereby granted, free of charge, to any person obtaining a |
| 7 | # copy of this software and associated documentation files (the "Software"), |
| 8 | # to deal in the Software without restriction, including without limitation |
| 9 | # on the rights to use, copy, modify, merge, publish, distribute, sub |
| 10 | # license, and/or sell copies of the Software, and to permit persons to whom |
| 11 | # the Software is furnished to do so, subject to the following conditions: |
| 12 | # |
| 13 | # The above copyright notice and this permission notice (including the next |
| 14 | # paragraph) shall be included in all copies or substantial portions of the |
| 15 | # Software. |
| 16 | # |
| 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL |
| 20 | # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 23 | # IN THE SOFTWARE. |
| 24 | # |
| 25 | # Authors: |
| 26 | # Ian Romanick <idr@us.ibm.com> |
| 27 | |
| 28 | |
| 29 | # This script is used to run api_speed against several different libGL |
| 30 | # libraries and compare the results. See the show_usage function for more |
| 31 | # details on how to use it. |
| 32 | |
| 33 | |
| 34 | import re, os, sys, getopt |
| 35 | |
| 36 | class results: |
| 37 | def process_file(self, f): |
| 38 | self.cycles = {} |
| 39 | self.iterations = -1 |
| 40 | |
| 41 | for line in f.readlines(): |
| 42 | m = re.match("(\d+) calls to (.{20}) required (\d+) cycles.", line) |
| 43 | |
| 44 | if self.iterations != -1 and int(m.group(1)) != self.iterations: |
| 45 | raise |
| 46 | |
| 47 | # This could be done with lstrip, but the version of |
| 48 | # the Python library on my system doesn't have it. |
| 49 | # The installed version of Python is quite old. :( |
| 50 | |
| 51 | temp = m.group(2) |
| 52 | function_name = None |
| 53 | for i in range(len(temp)): |
| 54 | if temp[i] != ' ': |
| 55 | function_name = temp[i:] |
| 56 | break |
| 57 | |
| 58 | if function_name == None: |
| 59 | raise |
| 60 | |
| 61 | self.cycles[ function_name ] = int(m.group(3)) |
| 62 | self.iterations = int(m.group(1)) |
| 63 | |
| 64 | |
| 65 | def show_results(self): |
| 66 | for name in self.cycles: |
| 67 | print "%s -> %f" % (name, float(self.cycles[name]) / self.iterations) |
| 68 | |
| 69 | |
| 70 | def compare_results(self, other): |
| 71 | for name in self.cycles: |
| 72 | if other.cycles.has_key(name): |
| 73 | a = float(self.cycles[name]) / self.iterations |
| 74 | b = float(other.cycles[name]) / other.iterations |
| 75 | p = (100.0 * b / a) - 100.0 |
| 76 | print "%- 20s %7.2f - %7.2f = % -6.2f (%+.1f%%)" % (name, a, b, a - b, p) |
| 77 | return |
| 78 | |
| 79 | |
| 80 | def make_execution_string(lib, iterations): |
| 81 | if lib == None: |
| 82 | return "./api_speed %u" % (iterations) |
| 83 | else: |
| 84 | return "LD_PRELOAD=%s ./api_speed %u" % (lib, iterations) |
| 85 | |
| 86 | |
| 87 | def show_usage(): |
| 88 | print """Usage: %s [-i iterations] {library ...} |
| 89 | |
| 90 | The full path to one or more libGL libraries (including the full name of the |
| 91 | library) can be included on the command-line. Each library will be tested, |
| 92 | and the results compared. The first library listed will be used as the |
| 93 | "base line" for all comparisons.""" % (sys.argv[0]) |
| 94 | sys.exit(1) |
| 95 | |
| 96 | |
| 97 | if __name__ == '__main__': |
| 98 | try: |
| 99 | (args, trail) = getopt.getopt(sys.argv[1:], "i:") |
| 100 | except Exception,e: |
| 101 | show_usage() |
| 102 | |
| 103 | iterations = 1000000 |
| 104 | try: |
| 105 | for (arg,val) in args: |
| 106 | if arg == "-i": |
| 107 | iterations = int(val) |
| 108 | except Exception,e: |
| 109 | show_usage() |
| 110 | |
| 111 | |
Ian Romanick | 63b2e42 | 2004-05-26 16:38:38 +0000 | [diff] [blame] | 112 | # If no libraries were specifically named, just run the test against |
| 113 | # the default system libGL. |
| 114 | |
| 115 | if len(trail) == 0: |
Ian Romanick | 77bbbb3 | 2004-05-26 17:12:56 +0000 | [diff] [blame^] | 116 | trail.append(None) |
| 117 | |
| 118 | |
| 119 | result_array = [] |
| 120 | names = [] |
| 121 | |
| 122 | for lib in trail: |
| 123 | s = make_execution_string( lib, iterations ) |
Ian Romanick | 63b2e42 | 2004-05-26 16:38:38 +0000 | [diff] [blame] | 124 | r = results() |
| 125 | r.process_file( os.popen(s) ) |
Ian Romanick | 77bbbb3 | 2004-05-26 17:12:56 +0000 | [diff] [blame^] | 126 | names.append(lib) |
Ian Romanick | 63b2e42 | 2004-05-26 16:38:38 +0000 | [diff] [blame] | 127 | result_array.append(r) |
Ian Romanick | 63b2e42 | 2004-05-26 16:38:38 +0000 | [diff] [blame] | 128 | |
| 129 | |
| 130 | # If the test was only run against one library, just show the results |
| 131 | # of the test run. Otherwise, compare each successive run against |
| 132 | # the first run. |
| 133 | |
| 134 | if len( result_array ) == 1: |
| 135 | result_array[0].show_results() |
| 136 | else: |
| 137 | for i in range(1, len( result_array )): |
| 138 | print "%s vs. %s" % (names[0], names[i]) |
| 139 | result_array[0].compare_results( result_array[i] ) |
| 140 | print "" |