Matevz Tadel wrote:
Matevz Tadel wrote:
Matevz Tadel wrote:
Matevz Tadel wrote:
Dan Espen wrote:
Matevz Tadel <matevz.ta...@cern.ch> writes:
Hi,
First, as this is my first post here, thanks a lot for this
excellent product.
I've been using fvwm since 1995 and it has never failed me.
I've recently upgraded my desktop to fedora 10 x86_64, fvwm --version
fvwm 2.5.26 compiled on Aug 30 2008 at 13:20:30
with support for: ReadLine, Stroke, XPM, PNG, SVG, Shape, XShm,
SM, Bidi text,
Xinerama, XRender, XCursor, XFT, NLS
I use FvwmIconMan to arrange my windows and with this version the
redraw became
very slow - it takes ~2 seconds to append 100 windows after a page
switch.
Each item is added independently, so the icon-man slowly grows (or
shrinks).
I was searching for an option to control this behaviour but could
not find any,
so I thought I'd ask if there is any way around this.
We saw your post yesterday.
Thanks ... I thought it went into trash as I was not subscribed yet.
I'm guessing no one has answered because no one knows the answer.
OK, thanks ... i'll try to trace it down myself and report.
Finally got the time to look into this ... traced it down to a
XFlush() at the end of modules/FvwmIconMan/xmanager.c::draw_button().
If I just comment it out everything seems to work fine.
Sorry, it might have been a false report ... before leaving my office
I restarted also my desktop machine (been testing on another one) and
the problem was still there. Had no time to cross-check, might be that
I did something stupid.
I have more info now, this time a bit more substantial :)
The two machines are too different to really compare (the test machine
runs slc-4, a variant of rhel-4 [x86], my desktop is fedora-10
[x86_64]). The removal of XFlush() in draw_button() really helped on the
old machine, but the symptoms were not so bad to start with. So .. I'll
focus on my desktop now (f10, x86_64).
I ran fvwm with callgrind and the results are most revealing.
I created 140 windows, the iconman buttons were put into one manager
with 2 vertical columns. Then I switched to another page, and did the
following:
1. enable callgrind instrumentation for FvwmIconMan
2. switch to the page with 140 windows
3. switch back
4. disable instrumentation
During this run it became obvious even visually that the whole manager
is redrawn each time a new iconman button is added (due to callgrind
slowdown).
I put the output (and my fvwm2rc) on:
<http://mtadel.home.cern.ch/mtadel/fvwm-iconman/>
(I use kcachegrind to view the callgrind output, a meaningfull
screenshot is also there.)
As you can see, 92% of time is spent in CombineChars() ... and it is
called 19759 times. This supports the above observation that all already
existing buttons are redrawn each time a new one is added/removed:
(1 + 2 + ... + 140) * 2 = 141 * 70 * 2 = 19740
The draw_button() itself is called 66.8k times, I really don't
understand where this number is coming from.
Anyway ... if we can track down where this multi-redraw is coming from
and eliminate it I'll be more than satisfied with the speedup :)
I got around the multiple redraws by checking if there is more data coming from
fvwm and only redrawing the managers when there is none (see attached diff). I
realize this is not a portable solution and can't go into the cvs. If you
consider this a proper soultion in spirit, I can rewrite it using select.
Best,
Matevz
<snip>
Index: fvwm.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmIconMan/fvwm.c,v
retrieving revision 1.66
diff -u -r1.66 fvwm.c
--- fvwm.c 7 Aug 2007 20:17:43 -0000 1.66
+++ fvwm.c 28 Jan 2009 19:10:09 -0000
@@ -675,9 +675,11 @@
}
}
+#include <sys/ioctl.h>
+
static void ProcessMessage(Ulong type, FvwmPacketBody *body)
{
- int i;
+ int i, bytes;
ConsoleDebug(FVWM, "fvwm message type: %ld\n", type);
@@ -832,11 +834,15 @@
check_managers_consistency();
- for (i = 0; i < globals.num_managers; i++)
+ ioctl(fvwm_fd[1], FIONREAD, &bytes);
+ if (bytes == 0)
{
- if (drawing(&globals.managers[i]))
+ for (i = 0; i < globals.num_managers; i++)
{
- draw_manager(&globals.managers[i]);
+ if (drawing(&globals.managers[i]))
+ {
+ draw_manager(&globals.managers[i]);
+ }
}
}