Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / DBP Application CPU limiter...easy trick..

Author
Message
Zep
21
Years of Service
User Offline
Joined: 31st Aug 2002
Location: From PA, USA. Currently reside in Hanoi, Vietnam
Posted: 3rd Mar 2018 06:10
function DoSleep(MS as dword)
if DLL EXIST(1) = 0 then LOAD DLL "kernel32.dll", 1
CALL DLL 1, "Sleep", MS
endfunction


do
sync
DoSleep(1)
loop

I don't know why it works, but it does (on winxp). CPU % drops from 99% to 0%. Program still functions as normal.
zero32
7
Years of Service
User Offline
Joined: 28th Jul 2016
Location:
Posted: 3rd Mar 2018 08:24 Edited at: 3rd Mar 2018 08:25
But dark basic already has this with "sync sleep 1":

do
sync
sync sleep 1
loop
"It is only slightly easier than changing all sugar in a cake into stevia after it has already been baked" -Bisqwit
Zep
21
Years of Service
User Offline
Joined: 31st Aug 2002
Location: From PA, USA. Currently reside in Hanoi, Vietnam
Posted: 3rd Mar 2018 09:39 Edited at: 3rd Mar 2018 09:41
Yes, you're right of course.

But

Sync
DoSleep(1)

uses less memory than

sync
sync sleep 1.

About 40K less
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 3rd Mar 2018 13:12
I wonder why?
WickedX
15
Years of Service
User Offline
Joined: 8th Feb 2009
Location: A Mile High
Posted: 3rd Mar 2018 13:56 Edited at: 3rd Mar 2018 14:01
Dbro's Sync Sleep function sets a flag used in the internal loop that calls the sleep function. You do not need to use it in the do loop.
Mage
17
Years of Service
User Offline
Joined: 3rd Feb 2007
Location: Canada
Posted: 3rd Mar 2018 15:44 Edited at: 3rd Mar 2018 16:30
The reason why you are dropping off to 0% is because there is no workload in that demonstration loop. So it appears oddly to be 100% effective. The 1ms (probably not really 1ms by the way) dominates the loop since nothing else is happening causing you to be "sleeping" 99% of the time. A real game would not do this and this exact function would not have much impact. Basically if you are aiming for 60 frames per second, you have about 16ms per frame. So if you get things done early that frame then you need the delay to be scaled to fill that remaining time instead of hard coding 1ms. Additionally you might actually want to undercut the scaled value by 1ms.

Additionally I noticed that coming out of the Sleep Sync you need to call Sleep Sync 0 to turn it off. When your frame rate dips too low where you don't want any Sleep Sync effect it will continue to eat frame rate unless turned off. I am hazy a little on this, but you might not be able to turn it off with that command if you just used the command to delay a few ms. You might need to Sync draw the frame, not delay any ms on that frame and then use Sleep Sync 0 . This is why my examples specifically use Sleep Sync 0 when there is meant to be no delay rather than merely omitting the command entirely for that frame.

So this is an excellent suggestionZep/Zero32 provided, but purely as is, it only works as a demo. It would need some extras to work in a full game.

For your benefit and anyone years from now using forum search:
I explored Sync Sleep with demos on several occasions.

Here I demonstrate the use. I also took the concept further, if the program is not real time why not have it sleep all the time until something is pressed.
https://forum.thegamecreators.com/thread/202812

Modular Code Library also has a version of this that has additional commands for enable/disable/set frame limit, also optionally manages camera sync mask:
https://forum.thegamecreators.com/thread/220759

WickedX wrote: "Dbro's Sync Sleep function sets a flag used in the internal loop that calls the sleep function. You do not need to use it in the do loop."

I have not seen the underlying low level code, and I speak only from using this in high level situations.

I'll also mention that there is another school of thought that says, sneak in some extra processing if you have spare time on each frame, which is almost never mentioned.
Zep
21
Years of Service
User Offline
Joined: 31st Aug 2002
Location: From PA, USA. Currently reside in Hanoi, Vietnam
Posted: 3rd Mar 2018 21:36
Quote: "The reason why you are dropping off to 0% is because there is no workload in that demonstration loop."


That was a piece of test code for example purposes. Works the same way in my project. Also uses less memory than Sync Sleep.
Mage
17
Years of Service
User Offline
Joined: 3rd Feb 2007
Location: Canada
Posted: 3rd Mar 2018 22:28
Sure, use which you prefer. I won't sweat 40k of memory when it's a DirectX video game.
Zep
21
Years of Service
User Offline
Joined: 31st Aug 2002
Location: From PA, USA. Currently reside in Hanoi, Vietnam
Posted: 4th Mar 2018 10:31
Quote: "I won't sweat 40k of memory when it's a DirectX video game."


Of course YOU wouldn't. But your comment doesn't surprise me AT ALL
Zep
21
Years of Service
User Offline
Joined: 31st Aug 2002
Location: From PA, USA. Currently reside in Hanoi, Vietnam
Posted: 4th Mar 2018 11:08
Quote: "Dbro's Sync Sleep function sets a flag used in the internal loop that calls the sleep function. You do not need to use it in the do loop.
"



Oh! I missed this..I will have to try it.

So I only have to "set it and forget it"?
like

sync on
sync rate 0
sync sleep(1)

do
sync
loop

???

Unless I want to set it to 0 again?

If so, I'll run some more memory tests ( I was setting Sync Sleep to 1 every loop)
Mage
17
Years of Service
User Offline
Joined: 3rd Feb 2007
Location: Canada
Posted: 4th Mar 2018 14:32
Why don't you click that first link I provided and one of the code snippets there labelled CPU Friendly Frame Limiter will show you how to do this properly.
zero32
7
Years of Service
User Offline
Joined: 28th Jul 2016
Location:
Posted: 4th Mar 2018 22:35
WickedX wrote: "Dbro's Sync Sleep function sets a flag used in the internal loop that calls the sleep function. You do not need to use it in the do loop."

seems to work

but do we have something similar for graphic cards? i have a laptop with hybrid graphics intel + nvidia. when i run a dbpro app even only with a print command in a do loop it will show a gpu usage up to 40% in the windows 10 taskmanager.
"It is only slightly easier than changing all sugar in a cake into stevia after it has already been baked" -Bisqwit
Mage
17
Years of Service
User Offline
Joined: 3rd Feb 2007
Location: Canada
Posted: 5th Mar 2018 00:03 Edited at: 5th Mar 2018 00:26
That's because your frame rate is not being limited and you have a super high frame rate.



This still ties into what I am saying. You can't just call Sync Sleep 1 and just forget about it. It does not quite work that way, but it has a persistent effect. It does remember the setting, so you can call it one time and continue to see effects. That's only a piece of a larger picture.

The documentation says Sleep Sync 500 should delay for 500ms and be CPU friendly. This does not happen it's not that reliable. I suspect the OS doesn't care and will hand CPU control back to the program early. Probably after only 1 ms.

Instead you place Sync Sleep 1 in a while loop and when the time is up exit the loop. This will cause the app to continually hand the CPU back to the OS until enough of a delay has passed. Remember to use Sync Rate 0 if frame rate dips too low or you will reduce frame rate even more. I think this entire behavior is fuzzy, contradicts the documentation, and could probably use a more detailed explanation.

Because the frame rate is actually being limited, GPU usage will be greatly reduced.

Zep
21
Years of Service
User Offline
Joined: 31st Aug 2002
Location: From PA, USA. Currently reside in Hanoi, Vietnam
Posted: 5th Mar 2018 00:56
The problem I see with
Sync Sleep(1)

Is the frame-rate.

In the small example (on my machine).

Sync Sleep(1) shows 175 FPS

On the other hand.

DoSleep(1) show 350 FPS

Both sleeps do drop the CPU usage to practically 0.

Not sure why. And honestly, I'm not sure if using either option is actually showing the true frame-rate. Either sleep option drops the FPS, but I haven't noticed any lack of performance in my bigger projects with DoSleep(1)

Zep
21
Years of Service
User Offline
Joined: 31st Aug 2002
Location: From PA, USA. Currently reside in Hanoi, Vietnam
Posted: 5th Mar 2018 01:18
BTW, using no sleeps, the FPS is around 1000.

Ortu
DBPro Master
16
Years of Service
User Offline
Joined: 21st Nov 2007
Location: Austin, TX
Posted: 5th Mar 2018 02:12
How do each of these compare to matrix1 nice sleep? (does same thing)
http://games.joshkirklin.com/sulium

A single player RPG featuring a branching, player driven storyline of meaningful choices and multiple endings alongside challenging active combat and intelligent AI.
WickedX
15
Years of Service
User Offline
Joined: 8th Feb 2009
Location: A Mile High
Posted: 5th Mar 2018 02:55
Just to clarify, these are the internal functions relating to Sync Sleep. The first is the internal function for Sync Sleep itself. The second is where and how the sleep function is injected.





I have run some tests on my quad core Windows 8.1 system with a somewhat lengthy project. With the program running uncapped, Task Manager show the program using 25% of the CPU with a frame rate returned by Screen FPS @ 145. Setting the processor friendly flag with an initial Sync Sleep 1 reduces the CPU cycles to 3% but, also reduces the frame rate to around 60. With Mage's SyncScreen function the program uses 100% of the core and reduces the frame rate further.

Mage: You seem to have a very intelligent intuition about how things work. But I cannot help think if your program can take the reduction in frame rate that simply setting the processor friendly flag is about the best you can hope for. Looking at your Standby Mode Example I can't see any real benefit. I will test further before making jugement.
Zep
21
Years of Service
User Offline
Joined: 31st Aug 2002
Location: From PA, USA. Currently reside in Hanoi, Vietnam
Posted: 5th Mar 2018 03:29
if(g_bProcessorFriendly) Sleep(1);



Same as the DoSleep(1) function I posted, without all the extra overhead.

Doesn't "sync" already pass off through to the windows message pump? Now it would be doing it twice a loop with "sync sleep"+"sync".. I think.
Zep
21
Years of Service
User Offline
Joined: 31st Aug 2002
Location: From PA, USA. Currently reside in Hanoi, Vietnam
Posted: 5th Mar 2018 03:46
Modified mine a bit

Start of program out of the main loop call this function:
function DoSleepLoad()
if DLL EXIST(1) = 0 then LOAD DLL "kernel32.dll", 1
endfunction

In the main loop use DoSleep(1):

function DoSleep(MS as dword)
CALL DLL 1, "Sleep", MS
endfunction

No sense in doing the "if dll exist..." every loop.
WickedX
15
Years of Service
User Offline
Joined: 8th Feb 2009
Location: A Mile High
Posted: 5th Mar 2018 03:59
Your function is basically the same as setting the processor friendly flag, So, why re-invent the wheel.? With the simple do nothing demo we started with, Task Manager reported your function using 5x the memory as simply setting the processor friendly flag with Sync Sleep.
Zep
21
Years of Service
User Offline
Joined: 31st Aug 2002
Location: From PA, USA. Currently reside in Hanoi, Vietnam
Posted: 5th Mar 2018 04:32
My task manager shows my function using 40K less memory than sync sleep+sync. I posted my results up thread (3rd post).
WickedX
15
Years of Service
User Offline
Joined: 8th Feb 2009
Location: A Mile High
Posted: 5th Mar 2018 04:55
You do understand, I'm taking about setting the processor friendly flag with Sync Sleep outside of the do/loop?

Zep
21
Years of Service
User Offline
Joined: 31st Aug 2002
Location: From PA, USA. Currently reside in Hanoi, Vietnam
Posted: 5th Mar 2018 04:59
Quote: "You do understand, I'm taking about setting the processor friendly flag with Sync Sleep outside of the do/loop?
"


I do. But same memory result out of loop or in the loop.
Mage
17
Years of Service
User Offline
Joined: 3rd Feb 2007
Location: Canada
Posted: 5th Mar 2018 05:00 Edited at: 5th Mar 2018 05:07
WickedX wrote: "Mage: You seem to have a very intelligent intuition about how things work. But I cannot help think if your program can take the reduction in frame rate that simply setting the processor friendly flag is about the best you can hope for. Looking at your Standby Mode Example I can't see any real benefit. I will test further before making jugement."

Well considering I've tested the code, this should be interesting. You'll notice it came with a screenshot showing the result too.



I check an intel laptop, the code does not work. I check an AMD workstation and I find that it does work. I feel betrayed:


But then I check the CPU friendly frame limiter included in my modular code library and it works on both computers:


What I am saying appears to still hold true.
WickedX
15
Years of Service
User Offline
Joined: 8th Feb 2009
Location: A Mile High
Posted: 5th Mar 2018 05:21 Edited at: 5th Mar 2018 05:22
I think system differences may be why we're getting different statistics. Zep is using an old Windows XP system and I'm using a Asus Transformer. Mage, you probably have a super fast gaming system. Could be the reason for your results. I am interested to know how just setting the processor friendly flag compares on your system. Zep, have to take your word for it, though I show opposite results.
Mage
17
Years of Service
User Offline
Joined: 3rd Feb 2007
Location: Canada
Posted: 5th Mar 2018 05:34 Edited at: 5th Mar 2018 05:36
WickedX wrote: "I think system differences may be why we're getting different statistics. Zep is using an old Windows XP system and I'm using a Asus Transformer. Mage, you probably have a super fast gaming system. Could be the reason for your results. I am interested to know how just setting the processor friendly compares on your system. Zep, have to take your word for it, though I show opposite results."

I read the functions that you posted. I agree with your position, I just think I have put this to effective use. All I am doing is what you are saying except i am automating the turning on and off of the flag and adding a timing delay.

I have a very fast AMD workstation and a 2011 era intel laptop. They both work with the latest example I provided. Even if they were fast, they couldn't be fast enough to cheat the test.

I suspect this issue has something to do with compiler bugs.
I can't find out why my first example doesn't work and why the second does on the same laptop. The major difference is the functions and logic are laid out slightly differently. So the compiler might be doing something there.


I should also remind people the documentation says this:
DBP Help Documents wrote: "
PRINT "give half a second back to the operating system each cycle"
SYNC SLEEP 500
"
Mage
17
Years of Service
User Offline
Joined: 3rd Feb 2007
Location: Canada
Posted: 5th Mar 2018 05:46 Edited at: 5th Mar 2018 06:20
Also i notice that Sync Sleep 0 is a critical component of my example. Removing it causes the code to fail. This directly contradicts the idea of this merely being a flag since I appear to be setting it on many times then setting it off once before syncing. So as a flag it should be off. Yet there is still an effect despite being turned off.

This does not appear to behave like a flag.

Either this isn't the whole story or the compiler has bugs.
As this appears to be a Dark GDK snippet, perhaps DBP is implemented differently.

I just found that function in the DBP source code. I must have misread DARKSDK as DARKGDK.
Green Gandalf
VIP Member
19
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 5th Mar 2018 13:29
Quote: "I just found that function in the DBP source code. I must have misread DARKSDK as DARKGDK."


You are not alone.

Login to post a reply

Server time is: 2024-03-29 15:14:30
Your offset time is: 2024-03-29 15:14:30