How Can The Times Be Different?

Blitz3D Forums/Blitz3D Beginners Area/How Can The Times Be Different?

Sir Gak(Posted 2009) [#1]
Did the following code:
count1 = MilliSecs()
For x=1 To 100000000
Next
count2 = MilliSecs()

count3 = MilliSecs()
For x =1 To 100000000
Next
count4 = MilliSecs()

Print count2 - count1
Print count4 - count3
MouseWait
End

The loops are identical, yet I get a reading of about 416 for the first, and about 384 for the second. Shouldn't identical code take the same time? Yet every time I run it, the first is always slower than the second. What's going on? (P.S. I am running it with debug OFF).


KillerX(Posted 2009) [#2]
It's because its completely based on the cpu. It depends on how much processing power is in use ny other applications.


Sir Gak(Posted 2009) [#3]
That's not really an adequate answer. The same CPU (AMD single core) is running both loops, in the same program, sequentially at the same time. If its performance depended on (or was affected by) other programs that were running, then BOTH loops should execute in the same time measurement. Or, alternatively, if other programs were drawing CPU power away from the program, then there ought to be a randomness in the timing, as in, the first loop gets more time than the second when run at one occasion, but then when run on another occasion, the second loop ought to run faster.

Empirically, that is not what is happening. I have run the program again and again and again. The first loop ALWAYS takes more time than the second, even though there is no discernible difference between them.


SoggyP(Posted 2009) [#4]
Hello.

First, in a multi-tasking environment you can never guarantee how long things will take.

Second, try putting a delay at the start of the program just to see if that helps - you'll probably find that they still take different amounts of time but that it's more evenly balanced as to which takes longer.

Oh, and it's Thursday and has been snowing, so that probably affects it too.

Strangely, I have been getting more annoyed at computers not being consistent, and not being able to provide a platform where tasks are repeatable (and the results trustworthy). I kinda thought that was sort of the point.

Goodbye.


_PJ_(Posted 2009) [#5]
Have you tried this with a pre-compiled executable too?

To be fair to Blitz here, you should ideally give it an opportunity to ready itself after compil;ing and then setting up the display window etc. before getting to the core of the data manipulation, something like:


Delay 5000

WaitMouse()
count1 = MilliSecs()
For x=1 To 100000000
Next
count2 = MilliSecs()

count3 = MilliSecs()
For x =1 To 100000000
Next
count4 = MilliSecs()

Print count2 - count1
Print count4 - count3
MouseWait
End



Charrua(Posted 2009) [#6]
I agree with you Malice, but in the middle of the second loop (or first or none) chances are that the next packet of the internet conexion arrives or the mouse where moved, or..

Multitasking means that any process could probably be interrupted at any time, so Real Time is never guaranteed.

Take a look at the list of process that are active at any time. Ho knows exactly wich to stop?

I think that a software loop never should be executed if the aim is reach an exact period of time.

Juan


Warner(Posted 2009) [#7]
I think that in the longest of the two loops, the program itself is polling the keyboard/mouse input or doing some other background tasks.
By the way, if I try this, sometimes it just hangs:
Repeat

count1 = MilliSecs()
For x=1 To 10000000
Next
count2 = MilliSecs()

Print count2 - count1

count1 = MilliSecs()
For x=1 To 10000000
Next
count2 = MilliSecs()

Print count2 - count1

Forever

I think it is a good idea to stay away from using empty For..Next loops.


mtnhome3d(Posted 2009) [#8]
the times,they are a changin'


_PJ_(Posted 2009) [#9]
Well empty for/next loops are bad thing in my opinion, they dont serve a purpose, and if you are aiming for timed delays, use Delay or something like:

WaitABit=Millisecs()
While (Millisecs()-WaitABit)<5000
Wend

Sure, the delay in checking may be in reality 5001 millisecs or more, never less, but it will guarantee the CPU will move on as soon as it can :)


Zethrax(Posted 2009) [#10]
Something else to bear in mind is that the CPU may be caching similar blocks of code, which will cause a slowdown as the code is cached, and a speedup due to additional blocks of code being executed from the cache.

Writing robust code often means not making too many assumptions about the results returned by that code. Things like timing, float operations, etc, are often imprecise out of necessity, and you need to code with that in mind.


Ross C(Posted 2009) [#11]
Yeah, you can't rely on the cpu giving you the exact same results in a multitasking environment. Bill also has a good point. The CPU usually caches code that is being repeated frequently and recently, to speed up future operations.


jfk EO-11110(Posted 2009) [#12]
Code-Cache may be one reason, but some of you may remember we found out some time ago that there is a significant diffrence depending on the odd- or evenness of a jumping label in the binary code. A FOR loop is made of a jump-label, a counter variable and a conditional jump to the label.

Try adding some nonsense commands before you start the 2nd loop, eg. "dummy=0", with a bit of luck you'll be able to get both labels on an even address, and therefor the same speed.

Edit: due to system background tasks with a high priority you will never get the exact same results (on something like Win98 you may be able to stop all processes that are not neccessray, like Antivirus etc., on XP and Vista there's much more going on, things like frequent harddrive access).

I was however able to get a max diffrence of about 20ms (eg. 400 vs 420) with both labels on even adresses, but with an additional "dummy=1" the labels seemed to be no longer both on even addresses and it gave me about 100 ms diffrence and more.

This happens however only on some CPU labels, as far as I remember it's on AMD but not on Intel.


_PJ_(Posted 2009) [#13]
Code-Cache may be one reason, but some of you may remember we found out some time ago that there is a significant diffrence depending on the odd- or evenness of a jumping label in the binary code. A FOR loop is made of a jump-label, a counter variable and a conditional jump to the label.

Try adding some nonsense commands before you start the 2nd loop, eg. "dummy=0", with a bit of luck you'll be able to get both labels on an even address, and therefor the same speed.

Edit: due to system background tasks with a high priority you will never get the exact same results (on something like Win98 you may be able to stop all processes that are not neccessray, like Antivirus etc., on XP and Vista there's much more going on, things like frequent harddrive access). 

I was however able to get a max diffrence of about 20ms (eg. 400 vs 420) with both labels on even adresses, but with an additional "dummy=1" the labels seemed to be no longer both on even addresses and it gave me about 100 ms diffrence and more.


I wasnt aware of that odd/even differene.

Certainly there's a lot more behind the scenes than simply whatever is processed at the time, Overall, for simplicities' sake, I guess it's easier just to say there's a definite limit to the to the reasonable accuracy to which timing of running code can be judged.