summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephane Marchesin <stephane.marchesin@gmail.com>2010-12-19 23:50:00 -0800
committerStephane Marchesin <stephane.marchesin@gmail.com>2010-12-19 23:50:00 -0800
commit0b54940b7334ee1c25fcecab0c00f0bf5c23c0a0 (patch)
tree981f3d3f639c73ce5d2721df8a1a8021f8f02aa5
parent32b62fb19254793a231f221ec87958c6183755ed (diff)
Add a «summary» mode. Fix bugs.
-rw-r--r--README15
-rwxr-xr-xbuild5
-rw-r--r--epilogue.c58
-rw-r--r--gen.c27
-rw-r--r--prologue.c14
5 files changed, 106 insertions, 13 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..fad851b
--- /dev/null
+++ b/README
@@ -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
+
diff --git a/build b/build
index c01faaf..989e400 100755
--- a/build
+++ b/build
@@ -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
diff --git a/epilogue.c b/epilogue.c
index 2f13e2a..e2837f3 100644
--- a/epilogue.c
+++ b/epilogue.c
@@ -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;
}
diff --git a/gen.c b/gen.c
index d1c094c..3c22c7a 100644
--- a/gen.c
+++ b/gen.c
@@ -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);
diff --git a/prologue.c b/prologue.c
index 00f3ea3..513ef80 100644
--- a/prologue.c
+++ b/prologue.c
@@ -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);