diff options
| -rw-r--r-- | progs/tests/api_speed.c | 146 | ||||
| -rwxr-xr-x | progs/tests/api_speed.py | 143 | 
2 files changed, 289 insertions, 0 deletions
| diff --git a/progs/tests/api_speed.c b/progs/tests/api_speed.c new file mode 100644 index 0000000000..f42c73dfc9 --- /dev/null +++ b/progs/tests/api_speed.c @@ -0,0 +1,146 @@ +/* + * (C) Copyright IBM Corporation 2002 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL + * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file api_speed.c + * Simple test to measure the overhead of making GL calls. + *  + * The main purpose of this test is to measure the difference in calling + * overhead of different dispatch methods.  Since it uses asm/timex.h to + * access the Pentium's cycle counters, it will probably only compile on + * Linux (though most architectures have a get_cycles function in timex.h). + * That is why it isn't in the default Makefile. + *  + * \author Ian Romanick <idr@us.ibm.com> + */ + +#include <stdio.h> +#include <stdlib.h> +#define GL_GLEXT_PROTOTYPES +#include <GL/gl.h> +#include <GL/glext.h> +#include <GL/glut.h> + +#define inline __inline__ +#include <asm/timex.h> + +static float Width = 400; +static float Height = 400; +static unsigned count = 1000000; + + +static void Idle( void ) +{ +   glutPostRedisplay(); +} + +#define DO_FUNC(f,p) \ +   do { \ +      t0 = get_cycles(); \ +      for ( i = 0 ; i < count ; i++ ) { \ +	 f p ; \ +      } \ +      t1 = get_cycles(); \ +      printf("%u calls to % 20s required %llu cycles.\n", count, # f, t1 - t0); \ +   } while( 0 ) + +/** + * Main display function.  This is the place to add more API calls. + */ +static void Display( void ) +{ +   int i; +   const float v[3] = { 1.0, 0.0, 0.0 }; +   cycles_t t0; +   cycles_t t1; + +   glBegin(GL_TRIANGLE_STRIP); + +   DO_FUNC( glColor3fv, (v) ); +   DO_FUNC( glNormal3fv, (v) ); +   DO_FUNC( glTexCoord2fv, (v) ); +   DO_FUNC( glTexCoord3fv, (v) ); +   DO_FUNC( glMultiTexCoord2fv, (GL_TEXTURE0, v) ); +   DO_FUNC( glMultiTexCoord2f, (GL_TEXTURE0, 0.0, 0.0) ); +   DO_FUNC( glFogCoordfv, (v) ); +   DO_FUNC( glFogCoordf, (0.5) ); + +   glEnd(); + +   exit(0); +} + + +static void Reshape( int width, int height ) +{ +   Width = width; +   Height = height; +   glViewport( 0, 0, width, height ); +   glMatrixMode( GL_PROJECTION ); +   glLoadIdentity(); +   glOrtho(0.0, width, 0.0, height, -1.0, 1.0); +   glMatrixMode( GL_MODELVIEW ); +   glLoadIdentity(); +} + + +static void Key( unsigned char key, int x, int y ) +{ +   (void) x; +   (void) y; +   switch (key) { +      case 27: +         exit(0); +         break; +   } +   glutPostRedisplay(); +} + + +int main( int argc, char *argv[] ) +{ +   glutInit( &argc, argv ); +   glutInitWindowSize( (int) Width, (int) Height ); +   glutInitWindowPosition( 0, 0 ); + +   glutInitDisplayMode( GLUT_RGB ); + +   glutCreateWindow( argv[0] ); + +   if ( argc > 1 ) { +      count = strtoul( argv[1], NULL, 0 ); +      if ( count == 0 ) { +	 fprintf( stderr, "Usage: %s [iterations]\n", argv[0] ); +	 exit(1); +      } +   } + +   glutReshapeFunc( Reshape ); +   glutKeyboardFunc( Key ); +   glutDisplayFunc( Display ); +   glutIdleFunc( Idle ); + +   glutMainLoop(); +   return 0; +} diff --git a/progs/tests/api_speed.py b/progs/tests/api_speed.py new file mode 100755 index 0000000000..d209676261 --- /dev/null +++ b/progs/tests/api_speed.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python2 + +# (C) Copyright IBM Corporation 2004 +# All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, and/or sell copies of the Software, and to permit persons to whom +# the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL +# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# Authors: +#    Ian Romanick <idr@us.ibm.com> + + +# This script is used to run api_speed against several different libGL +# libraries and compare the results.  See the show_usage function for more +# details on how to use it. + + +import re, os, sys, getopt + +class results: +	def process_file(self, f): +		self.cycles = {} +		self.iterations = -1 + +		for line in f.readlines(): +			m = re.match("(\d+) calls to (.{20}) required (\d+) cycles.", line) + +			if self.iterations != -1 and int(m.group(1)) != self.iterations: +				raise + +			# This could be done with lstrip, but the version of +			# the Python library on my system doesn't have it. +			# The installed version of Python is quite old. :( + +			temp = m.group(2) +			function_name = None +			for i in range(len(temp)): +				if temp[i] != ' ': +					function_name = temp[i:] +					break + +			if function_name == None: +				raise + +			self.cycles[ function_name ] = int(m.group(3)) +			self.iterations = int(m.group(1)) + + +	def show_results(self): +		for name in self.cycles: +			print "%s -> %f" % (name, float(self.cycles[name]) / self.iterations) + + +	def compare_results(self, other): +		for name in self.cycles: +			if other.cycles.has_key(name): +				a = float(self.cycles[name])  / self.iterations +				b = float(other.cycles[name]) / other.iterations +				p = (100.0 * b / a) - 100.0 +				print "%- 20s %7.2f - %7.2f = % -6.2f (%+.1f%%)" % (name, a, b, a - b, p) +		return + + +def make_execution_string(lib, iterations): +	if lib == None: +		return "./api_speed %u" % (iterations) +	else: +		return "LD_PRELOAD=%s ./api_speed %u" % (lib, iterations) + + +def show_usage(): +	print """Usage: %s [-i iterations] {library ...} + +The full path to one or more libGL libraries (including the full name of the +library) can be included on the command-line.  Each library will be tested, +and the results compared.  The first library listed will be used as the +"base line" for all comparisons.""" % (sys.argv[0]) +	sys.exit(1) + + +if __name__ == '__main__': +	try: +		(args, trail) = getopt.getopt(sys.argv[1:], "i:") +	except Exception,e: +		show_usage() + +	iterations = 1000000 +	try: +		for (arg,val) in args: +			if arg == "-i": +				iterations = int(val) +	except Exception,e: +		show_usage() + + +	result_array = [] +	names = [] + + +	# If no libraries were specifically named, just run the test against +	# the default system libGL. + +	if len(trail) == 0: +		s = make_execution_string( None, iterations ) +		r = results() +		r.process_file( os.popen(s) ) +		result_array.append(r) +	else: +		for lib in trail: +			s = make_execution_string( lib, iterations ) +			r = results() +			r.process_file( os.popen(s) ) +			names.append(lib) +			result_array.append(r) + + +	# If the test was only run against one library, just show the results +	# of the test run.  Otherwise, compare each successive run against +	# the first run. + +	if len( result_array ) == 1: +		result_array[0].show_results() +	else: +		for i in range(1, len( result_array )): +			print "%s vs. %s" % (names[0], names[i]) +			result_array[0].compare_results( result_array[i] ) +			print "" | 
