Re: glib: gmain, perf, etc...



On Wed, 24 Oct 2001, Grant Taylor wrote:

> FWIW, I've gone on to implement my own main loop, hash tables, linked
> lists, and other structures.  Things now run about 5 times faster.
> GLIB is just a poor fit for my application ;(

hm, we'd always like to hear about areas where significant speed improvements
are possible ;)

>  - Memchunks appear to be really slow.  They actually show up in the
>    profiler, which is just alarming.  The memchunk code seems to be
>    storing complicated trees of chunks of blocks, and rooting around
>    in them for each allocation.

memchunks are scheduled for removal/replacement for this and a couple
of else reasons. i unfortunately didn't get a chance to tackle this
for 2.0 though ;(

>    I see the trashstack, but it's not clear why the trashstack logic
>    doesn't just get folded into memchunk.  Doing it separate means
>    that there are a wider variety of itty-bitty interim internal
>    structure nodes floating around than necessary, and it makes
>    efficient usage take extra work.

right, i needed something faster than memchunks to maintain free lists
of structures where caching made lots of sense. that's when trash stacks
went in.

>    I mangled various parts of glib to have a "disable freelists"
>    config option, so that this purification is useful.  
> 
>    [ My patches would be horribly old at this point, but the changes
>    were minor. ]

we had some patching efford going on in the past, both, to disable freed-struct
caches, and to zero-them out at free-time. you might want to take a look at
glib again.

>    The trick is that gmain is arranged to operate a single state
>    machine: either event handlers are reentrant, or they aren't, and
>    there's no grouping or masking features to alow finer control of
>    state machine scheduling.  I added a g_source_detach, which I use
>    to nondestructively detach all sources I need masked, but this is
>    quite ugly.  (If anyone wants it, just ask, but like I said it's
>    ugly - both as a thing to do and as code).

i don't remember the details, but owen had good reasons for not offering
source detachment (at least at this point).

>  - I'm having performance headaches with gmain.  It appears not to
>    treat timeout sources specially, which means that if you add many,
>    it gets really slow while it iterates the list every check,
>    prepare, or dispatch.  Seems like it should have some special
>    timeout treatment and keep timeouts separate and sorted, rather
>    than iterating over the list every time.

>    My test program (which "pings" an event back and forth inside
>    itself) slows down by 50 times when 1000 no-work random timeout
>    sources are added.  That's admittedly a lot of timeouts, but it
>    would be at least twice as fast if the timeouts were sorted and
>    treated a bit specially.

this is right, and glib still behaves that way.
adding hundreds of timeouts isn't exactly what the current code
was designed for, normal apps use one-shot timers and maybe 2 or 3
frequent ones. so the main loop behaves reasonably well for moderate
amounts of sources, and that's quite unlikely to change in the future.
however for timeouts specifically, a more advanced source could be
written that'd maintain multiple timout function from one main loop
source per thread. this'd only work as new timeout type, adding to
current API however, since our current timeouts already expose the
fact that each of them is a seperate main loop source, because they
hand out their source pointers or source attachment ids.
i guess owen's just going to accept a parallel timeout API in the
future if suddenly lots of apps start using big amounts of timers
at once which can be considered somewhat unlikely ;)

>    Are there any things one should or shouldn't do when using a gmain
>    to help it perform a bit more evenly?  As is I have timeouts coming
>    and going somewhat frequently, which is poor, but normally there
>    aren't as fatally large a number of them as in my tests.

for your case, you're best off implementing your own multi-timeout-source
that bothers the main loop with just a single source, and can handle
lots of timeouts in its own way (passing on only the smallest timeout
scheduled in its ->prepare() function).

>  - It would be useful to have in-place constructors for some of the
>    objects in the glib library.  For example, if I were to do this:
> 
>    struct foo {
>      int i;
>      GQueue q;
>    }
> 
>    g_queue_inplace_new(&q);


this comes up now and again (i've been requesting this myself for some time).
however, the problem is that we'd have to essentially duplicate lots of
our APIs, resulting in doubled maintenance, and doubling the learning curve
for newbies. compared to that, the resulting benefits become negligible.

>    ...and end up with a valid GQueue smack in my struct.  With
>    judicious use internal to glib, some glib things might even
>    benefit.  I'll maybe do some of this for any glib structures I can
>    continue using after I get my event loop straightened out and have
>    profiled the result.
> 
>    [ Most of my own structures operate in a non-allocating way;
>    obviously both have a place, but the glib ones tend to promote the
>    container variety more than they should. ]

i need to say that, eventhough owen and me cooked up the newly added GQueue
API, i'm not actually much in favour of it. we had a patch for GRing floating
around the list that didn't make 2.0, but is much more what i'd like to see
people use if they need a head&tail linked data structure. it might make it
into some future glib version.

>  - A skiplist would be very handy.  I know that Havoc turned down one
>    skiplist submission, which probably made sense given that that
>    implementation was a funky doubly-linked skiplist atop plain
>    malloc.  Even so, skiplists are way better than trees for a lot of
>    things, and seem like a good thing to have in glib.
> 
>    [ Skiplists are perfect for timers in event loops, btw.  You can
>    totally eliminate list iteration in the loop by using one. ]

right, it takes a good and well implemented patch to include this though
(or someone willing to work on such code based on comments given on this
list untill it gets "good and well implemented" ;)

>  - The g_log subsystem is frightfully slow, even for things that are
>    filtered out.  It runs vsprintf on the message *before* filtering.
>    When something is filtered, it should be zero or at most one
>    function calls, not a whole pile of formatting logic.

g_log is still on my list of things to change the internals of. the
current code is about 3 times more complex than it has to be, just
because the memory subsystem wants to report pathologic situations
through it as well ;(

>  - Is there a way to control the size of hash tables better?  One
>    should be able to define a fixed size up front and avoid all sorts
>    of dynamic resize costs.

probably, yeah. though owen recently changed the resizing logic somewhat,
so the dynamic resizing penalties now might not be as bad as you think.

---
ciaoTJ




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