Re: --gtk-unbuffered



At 15:20 25.02.01 -0500, Owen Taylor wrote:
>
>Hans Breuer <hans breuer org> writes:
>
>> Hi Owen, et. al,
>> while trying to further identify the performance bottlenecks
>> in current gtk+, I've added a runtime switch to globally
>> disable double buffering. (See patch below, ok to commit ?).
>
>Not OK. Double buffering changes the semantics, it's not just
>some cosmetic tweak.
>
If you have looked through my patch, you may have noticed, that it simply
changes the default for the GTK_DOUBLE_BUFFERED flag in gtk/widget.c, which
- if I recall correctly - can be done on a per widget basis through an API
call anyway.

>If double buffering is a major performance bottleneck on windows,
>something is wrong.
>
It isn't, but it is a major drawback to identify real bottlenecks.
Seven (!) seconds from clicking the labels button in testgtk until first
complete rendering of the labels window seems a little bit undifferent to
be optimized. Btw: this was measured with a stop watch.

With switched of double buffering one could see which of all the labels are
rendered that slow.

>What are you trying to achieve by turning off double buffering?
>
>> The slowest parts - compared to the times before Pango / GObject / 
>> Backing Store merge are:
>> 
>> testgtk::message dialog :
>> testgtk::labels : the "normal" text rendering is relatively ok, but
>> 	the rendering of auto-wrapped labels is at least twenty times
>> 	slower than before. While investigating possible sollutions
>> 	I stumbled over three functions, which all say something
>> 	about required optimization :
>> 
>> 	gtk_label_ensure_layout - probably called more often than needed
>> 
>> 	pango_layout_set_width ->
>> 	pango_layout_clear_lines : (called too often)
>> 		/* This could be handled separately, since we don't need to
>>        	* recompute log_attrs on a width change, but this is easiest
>>        	*/
>> 	pango_layout_get_extents(_internal) ->
>> 	pango_layout_check_lines - 
>> 
>> The sequence in gtk_label_ensure_layout () calls set_with and get_extents
>> up to five times, which cause the pango internal log_attrs to be destroyed
>> and recalculated constantly although the comment above says, that it would
>> not be necessary to do it at all, on a width change.
>> 
>> I'm afraid, that I don't understand pango internals enough to fix this
myself.
>> Could someone please take a look into it ?
>
>How are you measuring performance? "20 times slower" is not really
>a useful statement. 
>
First from experience/impression, but before I write a mail to a
mailing-list I  take a watch (or add some time check code to the sources). 

>If the original took 0.1 milliseconds, then do we care? Almost
>certainly not. If the original took 0.1 seconds, then we would
>care.
>
Here are some "hard" timings:

Opening the message boxes with testcode in gtk_label_ensure_layout before
the work and after it; using the glib g_get_current_time call. 

with (before) :
  g_print ("gtk_label_ensure_layout: %s %s",
           label->layout ? "L" : "-",
           label->wrap ? "W" : "-");
  g_get_current_time (&tv0);

and (after) :
  g_get_current_time (&tv1);
  g_print (" %dx%d %f\n", rwidth, rheight,
            (((float)tv1.tv_sec - tv0.tv_sec)
            + (tv1.tv_usec - tv0.tv_usec) / 1000000.0));

gtk_label_ensure_layout: L - 25x13 0.000000
gtk_label_ensure_layout: - - 15x13 0.000000
gtk_label_ensure_layout: - W 278x52 0.512000
gtk_label_ensure_layout: L - 15x13 0.000000
gtk_label_ensure_layout: L - 15x13 0.000000
gtk_label_ensure_layout: L W 278x52 0.515000
gtk_label_ensure_layout: - - 26x15 0.000000
gtk_label_ensure_layout: - W 278x52 0.485000
gtk_label_ensure_layout: L - 26x15 0.000000
gtk_label_ensure_layout: L - 26x15 0.000000
gtk_label_ensure_layout: L W 278x52 0.510000
gtk_label_ensure_layout: - - 15x13 0.000000
gtk_label_ensure_layout: - - 33x13 0.004000
gtk_label_ensure_layout: - W 278x52 0.495000
gtk_label_ensure_layout: L - 15x13 0.000000
gtk_label_ensure_layout: L - 33x13 0.000000
gtk_label_ensure_layout: L - 15x13 0.000000
gtk_label_ensure_layout: L - 33x13 0.000000
gtk_label_ensure_layout: L W 278x52 0.465000
gtk_label_ensure_layout: - - 18x15 0.000000
gtk_label_ensure_layout: - - 14x15 0.005000
gtk_label_ensure_layout: - W 278x52 0.485000
gtk_label_ensure_layout: L - 18x15 0.005000
gtk_label_ensure_layout: L - 14x15 0.000000
gtk_label_ensure_layout: L - 18x15 0.000000
gtk_label_ensure_layout: L - 14x15 0.000000
gtk_label_ensure_layout: L W 278x52 0.456000

Please notice that not only the auto-wrapped labes are render with
significant time requirement (about half a second), but the same
calculation is done twice, as to be seen by two times for each size. The
second operation may be caused by the different event semantics/order on
win32 compared to X11.

Here's the timing for testgtk::labels
...
gtk_label_ensure_layout: - W 297x91 0.860000
gtk_label_ensure_layout: - - 96x13 0.005000
gtk_label_ensure_layout: - W 297x91 0.775000
gtk_label_ensure_layout: - - 76x13 0.005000
gtk_label_ensure_layout: - - 224x30 0.050000
gtk_label_ensure_layout: - - 61x13 0.005000
...

>GtkLabel uses a quite inefficient algorithm for figuring out the
>requested size, which involves repeatedly re-laying out the
>text at different widths.
>
>But, it's not worth trying to fix this algorithm unless it actually
>produces _noticeably_ bad performance, especially since a fix
>would involve considerable increases in complexity.
> 
>From what timing needs do you think it is _noticeably_ bad performance ?
Is half a second for a simple four line text acceptable ? 
(I don't think so - otherwise I wouldn't have done the investigation at
all. And there are other things I would like to spend my time on, e.g. Dia
improvements. Finally I'm doing this in my spare time and get payed for
developing on a closed source high performance real-time imaging system.)

>> testgtk::color selection :
>> 	has a slightly unoptimized implementation, constantly recalculating 
>> 	masks etc. The Gimp color selctor shows, how much faster this could
>> 	be done, even on windoze :) Would a patch to improve performance be
>> 	considered for imclusion ?
>
>It's not noticeably slow on on Unix. So, it's probably revealing
>some problem in the Windows backend.
>
Looking at the source shows recreation of bitmap masks all the time, though
nothing changed (same size rendering). 
IHMO it is annoying to see the little dot always some pixels behind the
mouse cursor, but if I'm the only one ...

>Now, of course, some things may just be inherently slow/ineffecient
>with Win32 GDI, but I generally wouldn't expect a large difference.
>
BTW: how do _you_ measure performance ? Are you developing on a GHz Athlon
or better ? What about the graphics card ? What's the smallest machine
Gtk+2.0 should run on smoothly ?

>A patch that increases performance, would be be accepted if:
> 
> - It made sense
> - It was clean code
>
As stated in my original mail there is the same widget in the gimp code
base *and* it isn't slow. I think the source now in gtk originally came
from there, but maybe someone has made too clean code ? :-)
 
>But I think it would be worth quantifying the things that are
>slow on windows as compared to Unix, so we can either fix
>them or code around them. 

Which would be a much more difficult task than identifying the actual slow
parts of the code. Some things which I haven't measured but keep in mind
when actually codeing fast implementations:

- Invalidate happens often, so provide fast redrawing for your display
parts. Don't rely on cacheing from the "Display Server". (IHMO this isn't
that important on X because the X Client (or is it the Server ? :-)
probably caches a lot of the data to display, because otherwise it would
need to get the new data over a possibly slow wire)

- Allow to invalidate/redraw only parts of your display data if rendering
the whole takes a long time.

- Provide multithreading. Every window on windoze can have it's own
MessageHandler function living in it's own thread. Let them handle
redrawing almost indepentently, e.g. without requiring data from another
thread.

>When I code for X, the cardinal rule is "avoid round 
>trips to the server", and if you do
>that, you can be astoundingly inefficient and still get
>decent performance.
>
But providing effective implementations doesn't hurt, does it ?

>But I don't have much of a sense of what's going on with
>performance and the Win32 port.
> 
IMO the main problem appears to be relying on a well known sequence of
events in specific order, but the event mapping from Gtk/X to Win32 is one
of the most complex parts in the port and it seems to work surprisingly
well. Additinally I have almost no clue about programming on X ...
 
>> testgtk::file selection : (takes some seconds to show up in the gtk build
>> 	directory)
>> 	requires further investigation. My current guess is, that the
>> 	whole file lists gets caculated (and rendered?) before showing
>> 	the dialog.
>
>No, that's not it. And it is, again, not noticeably slow on
>Unix.
I tried to cross check on Linux, but it was disrupted by a not building
glib (something about undefined GLIB_SIZEOF_LONG in gmem.c). But I dindn't
expect it to be that slow on Linux either. 

The three points noticed above are the _main_ performance problems with
current gtk (Opening a file dialog shouldn't take such a long time (4.5
secs) to show up, even if in a directory with 573 files.

Thanks for your help,
	Hans
-------- Hans "at" Breuer "dot" Org -----------
Tell me what you need, and I'll tell you how to 
get along without it.                -- Dilbert




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]