diff options
author | Stephane Marchesin <stephane.marchesin@gmail.com> | 2010-12-19 23:50:00 -0800 |
---|---|---|
committer | Stephane Marchesin <stephane.marchesin@gmail.com> | 2010-12-19 23:50:00 -0800 |
commit | 0b54940b7334ee1c25fcecab0c00f0bf5c23c0a0 (patch) | |
tree | 981f3d3f639c73ce5d2721df8a1a8021f8f02aa5 | |
parent | 32b62fb19254793a231f221ec87958c6183755ed (diff) |
Add a «summary» mode. Fix bugs.
-rw-r--r-- | README | 15 | ||||
-rwxr-xr-x | build | 5 | ||||
-rw-r--r-- | epilogue.c | 58 | ||||
-rw-r--r-- | gen.c | 27 | ||||
-rw-r--r-- | prologue.c | 14 |
5 files changed, 106 insertions, 13 deletions
@@ -0,0 +1,15 @@ +Glouton + +Description +----------- +Glouton is a command line low-overhead OpenGL performance tracer, both for driver and application authors. +The goal is to quickly and efficiently provide you with the information you need to tune your software. + +Compiling +--------- +./build + +Usage +----- +LD_PRELOAD=./libGL.so /usr/bin/myapp + @@ -3,7 +3,8 @@ rm -f libGL.so gcc -O2 gen.c -o gen `xml2-config --libs --cflags` &&\ ./gen &&\ -gcc -O2 -s -c -fPIC -DPIC main.c -o main.lo &&\ -ld -Bshareable -o ./libGL.so main.lo -lm -ldl +gcc -Os -s -c -fPIC -DPIC main.c -o main.lo &&\ +ld -Bshareable -o ./libGL.so main.lo -lm -ldl &&\ +strip libGL.so #rm -f main.c main.lo gen @@ -9,6 +9,49 @@ __GLXextFuncPtr glXGetProcAddress(const GLubyte *name) return glXGetProcAddressARB(name); } +static void (*rtld_fini_func)(void); + +static int compare(const void* a, const void* b) +{ + int v1 = *(int*)(a); + int v2 = *(int*)(b); + return total_time[v1]<total_time[v2]?1:-1; +} + +static void exit_func() +{ + rtld_fini_func(); + if (trace_summary) + { + uint64_t all = 0; + int i; + int* findex = (int*)malloc(sizeof(int)*num_funcs); + + for(i = 0 ; i < num_funcs ; i++) + { + all += total_time[i]; + findex[i] = i; + } + + qsort(findex, num_funcs, sizeof(int), compare); + + printf("Function Name \t\t\ttotal(us) \ttotal(%%) \t #calls\t avg us\n"); + for(i = 0 ; i < num_funcs ; i++) + { + int real_index = findex[i]; + if (total_calls[real_index]) + { + printf("%s",get_proc_list[real_index].name); + int j; + for(j=0;j<max(25-strlen(get_proc_list[real_index].name),0);j++) + printf(" "); + printf("\t%8llu \t%7.3f \t%9d \t%10.5f\n", total_time[real_index],total_time[real_index]*100.0/(float)all,total_calls[real_index],total_time[real_index]/(float)total_calls[real_index]); + } + } + free(findex); + } +} + /* Modify the __start function by overiding this function */ int __libc_start_main(int(*main_fct)(int, char **), int argc, char ** ubp_av,void (*init) (void), void (*fini) (void), @@ -28,10 +71,12 @@ int __libc_start_main(int(*main_fct)(int, char **), int argc, /* open library (NOTE: you may need to change this filename!) */ void* lib_handle_libGL = NULL; char* libGL_places[] = { - "/usr/lib64/libGL.so", + "/usr/lib64/libGL.so.1", "/usr/lib64/mesa/libGL.so.1", - "/usr/lib/libGL.so", + "/usr/lib64/libGL.so", + "/usr/lib/libGL.so.1", "/usr/lib/mesa/libGL.so.1", + "/usr/lib/libGL.so", NULL }; @@ -47,10 +92,15 @@ int __libc_start_main(int(*main_fct)(int, char **), int argc, /* get the host getprocaddress function */ lib_glXGetProcAddressARB = dlsym(lib_handle_libGL, "glXGetProcAddressARB"); - + + memset(total_time, sizeof(total_time), 0); + memset(total_time, sizeof(total_calls), 0); + functable_init(); - int r= func(main_fct, argc, ubp_av, init, fini, rtld_fini, stack_end); +// int r= func(main_fct, argc, ubp_av, init, fini, rtld_fini, stack_end); + rtld_fini_func = rtld_fini; + int r= func(main_fct, argc, ubp_av, init, fini, exit_func, stack_end); return r; } @@ -424,16 +424,21 @@ int main() // generate the function body - fprintf(file_wrapped,"\tprintf(\"gl%s \");\n",func_name); + fprintf(file_wrapped,"\tuint64_t before, after;\n"); + fprintf(file_wrapped,"\tif (trace_perfunc) {\n"); + fprintf(file_wrapped,"\t\tprintf(\"gl%s\\n\");\n",func_name); + for(i=0;i<=np;i++) { if (strcmp(nameparam[i],"UNUSED")==0) continue; - fprintf(file_wrapped,"\tprintf(\"%s \",%s %s);\n",type_print(type[i]),type_cast(type[i]),nameparam[i]); + fprintf(file_wrapped,"\t\tprintf(\"%s \",%s %s);\n",type_print(type[i]),type_cast(type[i]),nameparam[i]); } + fprintf(file_wrapped, "\t\tprintf(\"\\n\");\n"); + fprintf(file_wrapped, "\t}\n"); - fprintf(file_wrapped,"\tuint64_t before = gettime64();\n"); + fprintf(file_wrapped,"\tbefore = gettime64();\n"); // " int ret = ((void*)(int,int,int))functable[123](a,b,c)" fprintf(file_wrapped, "\t"); @@ -461,8 +466,15 @@ int main() fseek(file_wrapped,-1,SEEK_CUR); fprintf(file_wrapped,");\n"); - fprintf(file_wrapped,"\tuint64_t after = gettime64();\n"); - fprintf(file_wrapped,"\tprintf(\"%%llu\\n\",(unsigned long long)(after - before));\n"); + fprintf(file_wrapped,"\tafter = gettime64();\n"); + fprintf(file_wrapped,"\tif (trace_perfunc) {\n"); + fprintf(file_wrapped,"\t\tprintf(\"%%llu\\n\",(unsigned long long)(after - before));\n"); + fprintf(file_wrapped, "\t}\n"); + + fprintf(file_wrapped,"\tif (trace_summary) {\n"); + fprintf(file_wrapped,"\t\ttotal_time[%d] += (after - before);\n", fnum); + fprintf(file_wrapped,"\t\ttotal_calls[%d] ++;\n", fnum); + fprintf(file_wrapped, "\t}\n"); if (type_match(return_type) != 0) fprintf(file_wrapped,"\treturn ret;\n"); @@ -483,7 +495,10 @@ int main() }//fin while final - fprintf(file_getprocaddr, "};\n"); + fprintf(file_getprocaddr, "};\n\n"); + fprintf(file_getprocaddr, "static uint64_t total_time[%d];\n\n", fnum); + fprintf(file_getprocaddr, "static uint64_t total_calls[%d];\n\n", fnum); + fprintf(file_getprocaddr, "static int num_funcs = %d;\n\n", fnum); fprintf(file_functable,"}\n\n"); fclose(file_wrapped); @@ -3,15 +3,27 @@ #include <stdio.h> #include <stdlib.h> #include <stdint.h> +#include <unistd.h> +#include <string.h> #include <dlfcn.h> #include <sys/time.h> #include <GL/gl.h> #include <GL/glx.h> +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) + static PFNGLXGETPROCADDRESSPROC lib_glXGetProcAddressARB; -uint64_t gettime64() +// dump time for each function call +static const int trace_perfunc = 0; +// dump the total time per function +static const int trace_summary = 1; +// dump the shader programs² +static const int trace_shaders = 0; + +static uint64_t gettime64() { struct timeval tv; gettimeofday(&tv, NULL); |