Package: qprof
Version: 0.5.2-5
Severity: normal
Hello.
I am interested in profiling a Cairo application, not the application
code but instead the functions of my application that are waiting the most
time for Cairo, the X server and my video card, to finish the operation; that
way I can optimize my use of Cairo in the parts of my application that are
most important.
I couldn't find the right tool for the job yet (tried oprofile, gprof,
ltrace, valgrind, and looked at sysprof webpages but it doesn't seem to be
useful neither) except QProf with the realtime option, because I need that
the profiler takes into account the time that a function sleeps or waits for
another process (X in this case) to finish.
I don't know if this is a bug or limitation of QProf, but it says that
99% of the time spent in my application is on an hexadecimal address.
Since I don't know how to ask for help directly to the authors or other
users of QProf and since there doesn't seem to be a bug tracking system, I am
recurring to you.
Maybe this could be fixed by using libunwind on i386 too? Or is libunwind
ia64 specific?
Well, here is the example program and QProf output:
$ cat cairoprofiletest.c
/*
Compile with:
cc -g -Wall -Wextra cairoprofiletest.c -o cairoprofiletest $(pkg-config
cairo-xlib-xrender --cflags --libs)
Add -pg to that if you want to use gprof.
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <cairo-xlib-xrender.h>
typedef struct xlib_closure
{
Display *dpy;
Drawable drawable;
} xlib_closure_t;
cairo_surface_t* create_xlib_surface (const int width, const int height,
void* * const closure)
{
xlib_closure_t *xc;
XSetWindowAttributes xwattr;
XRenderPictFormat *xrender_format;
Visual *xvisual;
xc = malloc (sizeof (xlib_closure_t));
if (!xc) {
fprintf (stderr, "Failed to allocate memory!\n");
exit (10);
}
xc->dpy = XOpenDisplay (NULL);
if (xc->dpy == NULL) {
fprintf (stderr, "Failed to open display: %s\n", XDisplayName(0));
exit (10);
}
xvisual = DefaultVisual (xc->dpy, DefaultScreen (xc->dpy));
xrender_format = XRenderFindVisualFormat (xc->dpy, xvisual);
if (xrender_format == NULL) {
fprintf (stderr, "X server does not have the Render extension.\n");
exit (10);
}
xwattr.override_redirect = True;
xc->drawable = XCreateWindow (xc->dpy, DefaultRootWindow (xc->dpy), 0, 0,
width, height, 0, xrender_format->depth, InputOutput, xvisual,
CWOverrideRedirect, &xwattr);
XMapWindow (xc->dpy, xc->drawable);
*closure = xc;
return cairo_xlib_surface_create_with_xrender_format (xc->dpy,
xc->drawable, DefaultScreenOfDisplay (xc->dpy), xrender_format,
width, height);
}
void destroy_xlib_resources (void* const closure)
{
xlib_closure_t* const xc = closure;
XDestroyWindow (xc->dpy, xc->drawable);
XCloseDisplay (xc->dpy);
free (xc);
}
void test (cairo_t* const cr, const int width, const int height,
const int iterations)
{
int i = iterations;
while (--i) {
cairo_set_source_rgb (cr, (double)(i)/(double)(iterations)/2.0,
(double)(i)/(double)(iterations)/1.5,
(double)(i)/(double)(iterations));
cairo_rectangle (cr, 0, 0,
(double)(width)*((double)(i)/(double)(iterations)),
(double)(height)*((double)(i)/(double)(iterations)));
cairo_fill (cr);
}
}
void testfast (cairo_t* const cr, const int width, const int height,
const int iterations)
{
test (cr, width/2, height/2, iterations);
}
void testslow (cairo_t* const cr, const int width, const int height,
const int iterations)
{
test (cr, width, height, iterations);
}
int main()
{
void *surface_closure;
cairo_surface_t *cs;
cairo_t *cr;
struct timeval tstart, tstop;
int msfast, msslow;
const int width = 700;
const int height = 500;
const int iterations = 10000;
cs = create_xlib_surface (width, height, &surface_closure);
cr = cairo_create (cs);
gettimeofday (&tstart, NULL);
testfast (cr, width, height, iterations);
gettimeofday (&tstop, NULL);
msfast = ((tstop.tv_sec - tstart.tv_sec) * 1000000.0
+ (tstop.tv_usec - tstart.tv_usec)) / 1000.0;
gettimeofday (&tstart, NULL);
testslow (cr, width, height, iterations);
gettimeofday (&tstop, NULL);
msslow = ((tstop.tv_sec - tstart.tv_sec) * 1000000.0
+ (tstop.tv_usec - tstart.tv_usec)) / 1000.0;
fprintf (stdout, "Elapsed times: fast %ims (%i%%), slow %ims (%i%%), total
%ims.\n",
msfast, (msfast*100)/(msfast+msslow),
msslow, (msslow*100)/(msfast+msslow),
msfast+msslow);
cairo_destroy (cr);
cairo_surface_destroy (cs);
destroy_xlib_resources (surface_closure);
return 0;
}
$ qprof -r ./cairoprofiletest
Elapsed times: fast 3656ms (21%), slow 13647ms (78%), total 17303ms.
qprof: /home/ivan/prg/pru/cairoprofiletest/cairoprofiletest: 1730 samples, 1730
counts
libc.so.6(__libc_malloc) 1 ( 0%)
libc.so.6(memcpy) 1 ( 0%)
libc.so.6(pthread_mutex_unlock) 1 ( 0%)
libcairo.so.2 2 ( 0%)
libcairo.so.2(cairo_matrix_transform_distance) 1 ( 0%)
libcairo.so.2(cairo_matrix_transform_point) 4 ( 0%)
libcairo.so.2(cairo_surface_reference) 8 ( 0%)
[0xb7f8e410] 1712 ( 99%)
$
Thanks for your help!
-- System Information:
Debian Release: lenny/sid
APT prefers testing
APT policy: (500, 'testing')
Architecture: i386 (i686)
Kernel: Linux 2.6.23.1 (PREEMPT)
Locale: LANG=es_UY, LC_CTYPE=es_UY (charmap=ISO-8859-1)
Shell: /bin/sh linked to /bin/dash
Versions of packages qprof depends on:
ii libc6 2.6.1-1+b1 GNU C Library: Shared libraries
qprof recommends no packages.
-- no debconf information
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]