The Purpose of Delay In a Loop

BlitzMax Forums/BlitzMax Beginners Area/The Purpose of Delay In a Loop

Hardcoal(Posted 2016) [#1]
Hi..
I would like to know, why do you put a delay in your loop
and how do you do it properly If so..?

I see many times on a Graphic Loop the command Delay..
Also I have a problem.. (mainly on Xors3D)
when I see the graphics works fine.. and suddenly there is a Lag..
the frame rate falls down to like 10 fps..
Is that have any relation to the Delay thing?

Regards.. Hardcoal


BlitzMan(Posted 2016) [#2]
Create your own timer using MilliSecs()
dont use delay.


xlsior(Posted 2016) [#3]
Is that have any relation to the Delay thing?


Without the delay, the loop will run as fast as it can, gobbling up 100% of CPU.
If you put a 'delay 1' in the loop, then it will wait periodically, and release some of these resources back to the rest of the system -- it can significantly lower your CPU usage, at the cost of having less time to do the work you -need- to do each frame


Kryzon(Posted 2016) [#4]
When you call Delay it sleeps your program, making it not use any CPU time:
http://www.blitzbasic.com/Community/posts.php?topic=105460#1284877

It's especially useful for when you 'know' exactly the period of time that you won't need any CPU use, so you call this to sleep your program during that time.

A proper way to use Delay in a loop depends on what you know, like the framerate of your game, and what you don't know yet, like the frame time (how long it took to produce the last frame of gameplay).
When you decide on a framerate for your game like 30 FPS or 60 FPS, you're establishing that you need at most 33 milliseconds (in 30 FPS) or 16 milliseconds (in 60 FPS) each frame. If a frame in your game takes longer to produce than that, the game is "falling behind" on the framerate (usually called a "lag" or "slowdown").

In case your frame time (how long it took to produce the last frame of gameplay) is less than the framerate, meaning, you have some spare time left, you can Delay for that spare time to save on CPU:

Const DESIRED_FRAMETIME:Int = 1000.0 / 30.0 'How many milliseconds there should be in a single frame, under a 30 FPS rate.

While (...)

	Local startTime:Int = Milliseconds() 'Get the time at the start of the frame.

	myGame.Update() 'Update the game.
	myGame.Render() 'Draw the game.

	Local frameTime:Int = Milliseconds() - startTime 'Get how long in milliseconds it took to finish this frame.

	'With this 'frameTime' value we can find out some things:

	Local spareTime:Int = DESIRED_FRAMERATE - frameTime
	If spareTime < 0 Then

		'The game is slower than it should be. Maybe lower the graphics effects and quality, the AI etc.?

	ElseIf spareTime > 0 Then

		'There is some spare time in this frame. It was finished in less time than 33 milliseconds.
		Delay( spareTime - 1 ) 'We can sleep for the remainder, but sleep one millisecond less than the remainder just for safety.

	EndIf

Wend



Hardcoal(Posted 2016) [#5]
I just tried to put Delay(16) on my loop and it made everything
slow.. but with Delay(1) all is ok..
so I dunno..

I havnt tried kryzon loop though.

since im using Xors3d and it works on 60fps atm..
I dont know if they didnt already added this delay naturally on their
engine..

@blitzman what do you mean create my own delay..?
just make a loop of like for.. next..?


AdamStrange(Posted 2016) [#6]
delay gives time back to the system and makes your program wait for a bit.

Think of it this way:
in any closed loop E.G: 10 goto 10. your program will take 100% of a single CPU. the program will run as fast as the system can handle, but will also monopolise the CPU.

This will mean a single CPU will be at 100% and run hotter and degrade, etc.

If your computer only has 1 CPU then this will possible crash the computer or cause it to freeze completely - there is no time for the computer to do anything else like read the mouse, etc

So you always need to give back some time for the system.

In the old days before multithreading/multitasking/multicpu this was not a problem as your program could do this because it was the only thing running.

We now live with computer that are always doing lots of things in the background.

If you don't give back some time (use a delay) this will mess with the OS.

So really you should never thing of a program as a single entity, but one that play nicely with others (give a little time back).

An example of a bad program that doesn't give time back would be one that makes a cpu run at 100%. You know precisely that there is a closed loop which is not giving time back - probably the main program loop

You could also use this to deliberately knobble a competitor (this is a real example from a very well know brand of high end control surfaces).
If you had a driver for some hardware that supported multiple protocols. say midi and your own protocol - but you really wanted people to use your protocol and not midi. use a closed loop for the midi scanning (100% cpu usage) and a proper main loop with time back for your own protocol (1% cpu) in your driver!!


Hardcoal(Posted 2016) [#7]
I guess that's also why my app used to get stuck from time to time..

For years lol i delayed this questioning about the use of delay.
I said to my self ill ask when the right time will come..


xlsior(Posted 2016) [#8]
I just tried to put Delay(16) on my loop and it made everything
slow..


16ms is how long it takes to show a single frame at 60Hz -- If you use delay(16) you're telling the CPU to go to sleep for 16ms, meaning that you're guaranteed to drop a frame each time you call that.


H&K(Posted 2016) [#9]
Nowadays for the level of program a single programmer produces you should be waiting for the system to allocate CPU to you, not the system waiting for you.