View Full Version : Arkanoid: "Sleep 10" to reduce CPU usage
ErosOlmi
05-06-2008, 20:31
This is about a post at http://community.thinbasic.com/index.php?topic=1792.msg13310#msg13310
_________________________________________________
Petr,
I'm not sure SLEEP 10 is the solution to reduce CPU usage especially on fast processors having multy core.
On those CPU SLEEP 10 add a visible stepping and does not reduce any CPU usage.
The method I think is best is to pass a time slice to Windows to manage events. And this is done using DOEVENTS or similar methods. But this is already done in thnBasic Core engine every time a WHILE keyword is encountered. To prove that, when you execute a UI script having a main WHILE/WEND loop, CPU is almost at zero even if thinBasic engine is parsing continuously message pump of the script.
I think you have to check inside TBGL module and see if after creating TBGL window you have a CALLBACK fucntion that handle the windows events. If you have, try to check if that callback is taking some time. If you have no CALLBACK for TBGL windo, create one that does not handle eny event but just pass them to the standard window function.
I will investigate more on this.
Ciao
Eros
Petr Schreiber
05-06-2008, 21:13
Hi Eros,
the window is created old good Petzold way, so pure Win32 window with callback WndProc.
It is executed approximately various number of times in second on my PC, but it does almost nothing :)
Processed messages are:
%WM_CREATE
%WM_ERASEBKGND
%WM_MOUSEWHEEL
%WM_SIZE
%WM_MOVE
%WM_CLOSE
%WM_DESTROY
%WM_SYSCOMMAND
So as you see, many of them get processed just once.
The whole WndProc take almost unmeasurable time, and is executed approximately few times a second in ideal case.
Petr
P.S. Following script shows 99% CPU on AMD Sempron 3400+ 64bit
while 1
wend
ErosOlmi
05-06-2008, 21:18
What value do you return in FUNCTION on %WM_ERASEBKGND notification message?
Petr Schreiber
05-06-2008, 21:19
Hi Eros,
FUNCTION = %TRUE
Petr
ErosOlmi
05-06-2008, 21:22
OK thanks, Return code not zero means you handle the event so ok.
P.S. Following script shows 99% CPU on AMD Sempron 3400+ 64bit
while 1
wend
That's because it is not using UI module.
I'm not on my computer so I cannot test right now but if it goes almost 100% CPU there must be something from my side.
Thanks I will check soon.
Petr Schreiber
05-06-2008, 21:27
I tried to use UI:
uses "UI"
while 1
wend
And this way I get from 45 to 55%
Thanks,
Petr
ErosOlmi
05-06-2008, 22:53
ATTENTION: use attached thinCore only for testing !!!!_________________________________________________
Petr,
please test attached thinCore.dll and see if it makes any difference.
Do not use any SLEEP or add any UI module in order not to influence your tests.
Thanks a lot
Eros
PS: File removed.
Petr Schreiber
05-06-2008, 23:06
How did you do that ;D
Seems to work ok! In some TBGL scripts it seems the FPS is suddenly limited to very stable 64 FPS or so, but in others ( TopDown, tbglBenchmark ) I get the same as before, so up to 850 FPS. Seems quite ok!
But CPU hogging is at very low level, mostly reported as 0 :)
Thanks thanks!,
Petr
ErosOlmi
05-06-2008, 23:07
What about CPU usage?
Petr Schreiber
05-06-2008, 23:11
Mostly 0%,
so perfect!
The "worst" was about 2% :)
Petr
ErosOlmi
05-06-2008, 23:15
You will not bealive it.
I changed my Power Basic IDLE message pump (executed during WHILE/WEND operations) from:
MACRO NewDoEvents
MacroTemp nde_Msg
Dim nde_Msg As TagMsg
If PeekMessage(nde_Msg, %Null, 0, 0, %PM_REMOVE) Then
TranslateMessage nde_Msg
DispatchMessage nde_Msg
End If
END MACRO
to
MACRO NewDoEvents
'GLOBAL nde_Msg AS TagMsg
MacroTemp nde_Msg
Dim nde_Msg As TagMsg
If PeekMessage(nde_Msg, %Null, 0, 0, %PM_REMOVE) <> 0& Then
If nde_Msg.message = %WM_QUIT Then
Else
TranslateMessage nde_Msg
DispatchMessage nde_Msg
End If
End If
END MACRO
I think the change that effect CPU is from:
If PeekMessage(nde_Msg, %Null, 0, 0, %PM_REMOVE) Then
to
If PeekMessage(nde_Msg, %Null, 0, 0, %PM_REMOVE) <> 0& Then
I will investigate further about this.
Ciao
Eros
Petr Schreiber
05-06-2008, 23:22
Incredible :D,
how did you found that ... I have no idea :)
But fact is that it works!
Perfect,
Petr
ErosOlmi
05-06-2008, 23:25
I Google http://www.google.com/search?hl=en&q=apisleep+function
And on the second link reported by Google I found this post: http://www.powerbasic.com/support/pbforums/showthread.php?t=11924
In there Michael Ritter reported a loop very similar to mine but with "<> 0&" boolean test. I tried and voilla, the magic.
_________________________________________________
On my Core Duo, CPU usage drop from fixed 50% (mainly one processor always 100% CPU) to 15-25 % variable CPU usage.
I confirm the effect is done by the test
<> 0&
instead of not logic comparison test.
I need some more confirmations because I have a lot of boolean tests made with just: IF variable THEN
Worth and investigation.
Eros
Petr Schreiber
05-06-2008, 23:27
I thought those tests are 100% equivalent,
good to know that they are not!
I have to go offline now or I will become zombie, but tommorow I will do some benchmarks ... very interesting.
Petr
ErosOlmi
06-06-2008, 05:27
Hold on.
I would like to give a kick in my back. I introduced a big mistake in the posted thinCore.dll version (now removed).
Reduction of CPU usage was due to a time slice I reserved to the OS adding an internal looper I left by mistake.
But with this looper, WHILE loops are too much slow.
I'm reconsidering the entire matter.
Maybe a sleep somewhere or better a new keyword that give some time to the OS is better.
Sorry for the above ... illusion.
ErosOlmi
06-06-2008, 06:27
I think I've got a good compromise.
Instead of adding an internal SLEEP that would influence all scripts and (worst) it would be something "imposed" by the engine, I've modified DOEVENTS keyword in such a way that, if executed, it will give some time slice to the OS reducing CPU usage.
So, download attached file and to see results, just add a DOEVENTS inside the main loop of the script or where you think it would be better to give time to CPU.
Regards
Eros
Petr Schreiber
06-06-2008, 09:34
Hi Eros,
I tried to use it like:
while tbgl_IsWindow(hWnd)
doevents
...
wend
... and it seems to work very nicely. Even with this "slowdowner" it is possible to reach framerates exceeding refreshrate of LCD while CPU is at nice 0-10%. Good job done, no need for kicking yourself :)
Petr