Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Widgets - General questions or Mixed problems » howto best Ctrl Refresh handling w/ MT & very frequent refreshes
Re: howto best Ctrl Refresh handling w/ MT & very frequent refreshes [message #26976 is a reply to message #26974] Wed, 16 June 2010 11:23 Go to previous messageGo to next message
cbpporter is currently offline  cbpporter
Messages: 1401
Registered: September 2007
Ultimate Contributor
Maybe your solution is a combination of the ideas in this thread. Can't you update only data in your threads and update your entire GUI at a fixed interval? Using a MVC model. You update your Model only. If you need to update a label and are worried about the label Refresh, update a string and in you "update view" method set that label. But you must make sure that your total number of updates in a given period of time is less than it would be if the threads would update at their own pace. Otherwise you wont get any performance benefit and your code will become very complex.
Re: howto best Ctrl Refresh handling w/ MT & very frequent refreshes [message #26977 is a reply to message #26972] Wed, 16 June 2010 12:05 Go to previous messageGo to next message
Sender Ghost is currently offline  Sender Ghost
Messages: 301
Registered: November 2008
Senior Member
luzr wrote on Wed, 16 June 2010 07:27


General word of advice: Do not be so eager to change U++ sources. Some time later you can find yourself standing on diverging platform :)


Hello, Mirek.

Well, I can understand your points: merging of view and controller together (from Model-View-Controller perspective) to simplify porting problems.
My points for Konstantin is just for possible path to start thinking about (what functions calls RefreshFrame, which called by it, etc.). After understanding this path can be optimized. For example, some Ctrl functions can be virtual and overriden by inherited class functions. But for now, this solved partially and not in all cases.

The main problem here, I think, is bottleneck and not only with Refresh, but also with functions called by SetData (which showed previous Jan example with cached data). Yes, in current state this bottleneck can be as minimal as possible.

So, I tried to solve the problem first (currently in simplified form), but not to change public sources without strong reason.
Re: howto best Ctrl Refresh handling w/ MT & very frequent refreshes [message #26980 is a reply to message #26977] Wed, 16 June 2010 15:43 Go to previous messageGo to next message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
thanks guys for the ideas. i think there is no other option, i will do it like that.

another more general questions arises:

my gui view for each device comes from an xml file, where i use ParentCtrl to invisibly group other Ctrls to be able to specify their common offsets, positions, extents, etc generally easy arange them. since its an audio device application there is quite a lot ctrls invoved and i use quite a lot ParentCtrl to organize them.

??? does the Ctrl tree depth matter ??? (i imagine yes).

imagine a deph of easily 20-25 Ctrls, so if the downmost (actually opaque ctrl) is updated/refresht, >>> does the refresh have to recompute *all* the tree path (i.e. from topmost, parent, forwarding the dirty rect to the children or something. i imagine this to happen when WM_PAINT gets executed, one needs to determine which ctrl is actually to be drawn. as i remember there is code for determining exactly this, which ctrl lies in the dirty rect)?

this could be another bottle neck. couldnt one speed up the search top-down by "marking" the "repaint" path bottom-up with a flag?

better explain:
a Ctrl's Refresh() marks itself as dirty target and marks the parents in path up to top as the path to go for the dirty Ctrl, when a WM_PAINT is received, one only needs to check which ctrl in the tree are marked...

but sure the current way is not bad anyway..some short explanations of interna would really help..

cheers

Re: howto best Ctrl Refresh handling w/ MT & very frequent refreshes [message #26983 is a reply to message #26980] Wed, 16 June 2010 17:17 Go to previous messageGo to next message
Sender Ghost is currently offline  Sender Ghost
Messages: 301
Registered: November 2008
Senior Member
Please, try to uncomment LLOG(x)/LTIMING(x) defines on the top of uppsrc/CtrlCore/CtrlDraw.cpp file to see some behaviour in the application logs compiled in debug mode.
Also, you can use Ctrl::ShowRepaint static function to see this visually with prefered refresh rate in milliseconds (e.g. with (Transparent/FullBack)Paint states for Ctrls globally activated by Ctrl::GlobalBackPaint static funciton):
GUI_APP_MAIN
{
	Ctrl::GlobalBackPaint(true);
	Ctrl::ShowRepaint(50); // 50 ms = 20 fps

[Updated on: Wed, 16 June 2010 17:18]

Report message to a moderator

Re: howto best Ctrl Refresh handling w/ MT & very frequent refreshes [message #26984 is a reply to message #26983] Wed, 16 June 2010 17:26 Go to previous messageGo to next message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
i'll try it..

do you have some hin concerning the repaint modell in upp? how is it done, what is the idea behind it?

thx
Re: howto best Ctrl Refresh handling w/ MT & very frequent refreshes [message #26985 is a reply to message #26984] Wed, 16 June 2010 18:47 Go to previous messageGo to next message
Sender Ghost is currently offline  Sender Ghost
Messages: 301
Registered: November 2008
Senior Member
kohait00 wrote on Wed, 16 June 2010 17:26


do you have some hint concerning the repaint model in upp? how is it done, what is the idea behind it?


Not exactly, except what I said before about MVC and cached data.
We can see following words from documentation for Ctrl::RefreshFrame:
Quote:


Marks requested rectangle of frame area for repainting. Actual repainting is deferred for performance reasons.


When application window moves or some application window(s) moves along it repaints appeared areas.
Also Mirek said about input queue.

May be, following caller graph diagram created by Doxygen and Graphviz programs for Ctrl::RefreshFrame (from CtrlCore perspective only) can be useful:

index.php?t=getfile&id=2587&private=0


Actual painting (e.g. for Windows operating system) happens in virtual Ctrl::WindowProc function:
LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
//...
	HWND hwnd = GetHWND();
	switch(message) {
//...
	case WM_PAINT:
		ASSERT(hwnd);
		if(IsVisible() && hwnd) {
			PAINTSTRUCT ps;
			SyncScroll();
			HDC dc = BeginPaint(hwnd, &ps);
			fullrefresh = false;
			SystemDraw draw(dc);
//...
			UpdateArea(draw, Rect(ps.rcPaint));
//...
			EndPaint(hwnd, &ps);
		}
		return 0L;

[Updated on: Fri, 18 June 2010 08:58]

Report message to a moderator

Re: howto best Ctrl Refresh handling w/ MT & very frequent refreshes [message #27019 is a reply to message #26758] Mon, 21 June 2010 16:52 Go to previous messageGo to next message
Sender Ghost is currently offline  Sender Ghost
Messages: 301
Registered: November 2008
Senior Member
As conclusion, I created following example to demonstrate this problem and solution.

index.php?t=getfile&id=2592&private=0

On the left side you can see normal behaviour of Upp application with about 100% CPU load periodically.
On the right side you can see reduced CPU load with using CachedCtrl class template and specified update rate.

The left and right sides of application can be activated with right mouse click and deactivated with left mouse click.

With Array<CachedCtrl<Ctrl> *> this example can be changed to support more types of Ctrls.

The source code of example attached to this message.
Re: howto best Ctrl Refresh handling w/ MT & very frequent refreshes [message #27035 is a reply to message #27019] Tue, 22 June 2010 11:24 Go to previous messageGo to next message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
thanks for the example.

i indeed could see performance wins applying the overall approach. so together with the example, we could consider this problem to be solved to a satisfactory degree.

i just try to sum up the things we learned here:

PROBLEM:
frequent, independant refreshes to a lot of Ctrl's (deep in tree or not) caused by different threads than the Main thread produce a high CPU load, becaause the Ctrl's are indeed refreshed one by one (or at least almost). additionally, the threads passing the refresh work over to the MainThread (using ICall interface etc.) are beeing slept for that time. -> main thread invokes Refresh just too often, because the Updates (that trigger the Refresh) are independant.

SOLUTION:
separate the data Update (SetData, SetText, SetLabel, etc) of the Ctrl's from the natural / automatic triggering of Refresh() (inside Ctrl's, unaccessible), by:

* using a cached class like the above (if you only use Get/SetData). it overloads the Get/SetData() and prevents the triggering of Refresh each time..

* (more complex) providing a caching database independant of Get/SetData() (or other Interface functions ).

both solutions conclude with a periodic Refresh() call for all (meanwhile) affected/changed Ctrl's. Refresh time does not need to be faster than 200 ms.

Re: howto best Ctrl Refresh handling w/ MT & very frequent refreshes [message #27036 is a reply to message #27035] Tue, 22 June 2010 11:45 Go to previous messageGo to next message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
for all those who are having app CRASHES when exiting the application, while a timer is running (triggering the refreshes on Ctrl's that dont exist anymore because of deletion). here an example solution with an Atomic variable, a bool flag and wait for an atomic state. any hints / advices / corrections welcome. so far it works for me.

sorry its just copy and paste from my application, with only some changes/deletes, but i hope the idea will be clear enough.

class ASPDevice
{
...
        ~ASPDevice() { DemoMode(false); } //will wait for timer to exit clean
	Atomic demo; //0=disabled, 1=running demo mode, 2=a timer cb is executing
        bool isdemo;
        IsDemoMode() const { return isdemo; }
...
}

void ASPDevice::DemoMode(bool b)
{
	bool _b = isdemo;
	isdemo = b;
	if(!_b && isdemo) //start only one time, maybe here is a problem still, because not atomic
	{
		ASSERT(AtomicInc(demo)==1);
		SetTimeCallback(0, THISBACK(GenDemoData), 2);
	}
	else if(_b && !isdemo)
	{
		KillTimeCallback(2); //very important, timer might be not executin currently
		AtomicDec(demo);
		while(AtomicRead(demo) > 0) Sleep(1);
		ASSERT(AtomicRead(demo)==0);
	}
}

void ASPDevice::GenDemoData()
{
	ASSERT(AtomicInc(demo)==2);

...
//do your refresh stuff here, dont forget an AtomicDec(demo) on error exits
...
	
	int a = AtomicDec(demo);
	if(a<=0) return; //if has been desabled, dont restart
	ASSERT(a>=0);
	ASSERT(IsDemoMode());
	SetTimeCallback(200, THISBACK(GenDemoData), 2); //inkl a jitter
}

Re: howto best Ctrl Refresh handling w/ MT & very frequent refreshes [message #27037 is a reply to message #27019] Tue, 22 June 2010 13:05 Go to previous messageGo to next message
tojocky is currently offline  tojocky
Messages: 607
Registered: April 2008
Location: UK
Contributor

Sender Ghost wrote on Mon, 21 June 2010 17:52

As conclusion, I created following example to demonstrate this problem and solution.

index.php?t=getfile&id=2592&private=0

On the left side you can see normal behaviour of Upp application with about 100% CPU load periodically.
On the right side you can see reduced CPU load with using CachedCtrl class template and specified update rate.

The left and right sides of application can be activated with right mouse click and deactivated with left mouse click.

With Array<CachedCtrl<Ctrl> *> this example can be changed to support more types of Ctrls.

The source code of example attached to this message.



Nice solution!
Re: howto best Ctrl Refresh handling w/ MT & very frequent refreshes [message #27038 is a reply to message #27035] Tue, 22 June 2010 15:36 Go to previous messageGo to next message
Sender Ghost is currently offline  Sender Ghost
Messages: 301
Registered: November 2008
Senior Member
kohait00 wrote on Tue, 22 June 2010 11:24


thanks for the example.


tojocky wrote on Tue, 22 June 2010 13:05


Nice solution!

Thanks. Main credits to Jan.
kohait00 wrote on Tue, 22 June 2010 11:24


additionally, the threads passing the refresh work over to the MainThread (using ICall interface etc.) are beeing slept for that time. -> main thread invokes Refresh just too often, because the Updates (that trigger the Refresh) are independant.


Seems, there exists some race condition to access Handle of Device Context (HDC), at least on Windows operating system.
kohait00 wrote on Tue, 22 June 2010 11:24


Refresh time does not need to be faster than 200 ms.


In particular example, refresh (update) rate can be set to 0 ms (or by using PostCallback).

[Updated on: Tue, 22 June 2010 16:12]

Report message to a moderator

Re: howto best Ctrl Refresh handling w/ MT & very frequent refreshes [message #27039 is a reply to message #27038] Tue, 22 June 2010 17:36 Go to previous message
kohait00 is currently offline  kohait00
Messages: 939
Registered: July 2009
Location: Germany
Experienced Contributor
Quote:


(or by using PostCallback).



this is actually what i am using. my timer function just postcallback's the refresher function, just to be sure that the main thread executes it in plain workflow, without sideeffects.

thus i coudl drop cpu usage about 80 %. thats not bad Smile, just like in your example.. impressive Smile
Previous Topic: GtkWidget inside U++
Next Topic: DONE: ColumnList with Ctrl's
Goto Forum:
  


Current Time: Thu Mar 28 21:25:11 CET 2024

Total time taken to generate the page: 0.01228 seconds