Thanks the tip, Dave. Never been "Profiled" before. (Well I have but that's another story for another time.) Nifty tool. Really couldn't be easier.
==================================
"Even when all the experts agree,
they may well be mistaken."
Bertrand Russell
==================================
Announcement
Collapse
No announcement yet.
Timer speed
Collapse
X
-
This is a classic case for sticking ' Profile "c:\Life.txt" ' at the end of PBMain. The time saved with John's tip sticks out like a sore thumb.
Leave a comment:
-
Originally posted by John Gleason View PostI looked at the Life code and had this thought: if you update the title information less frequently, you will see a speed improvement. So if you don't mind updating the title every say 10 generations, you might get ~14% speed improvement like I did.
Here's the counter I installed:
Code:' Incr Header_Set_Ctr 'John Geason suggestion, save time doing header instead of multiple times per second ' If Header_Set_Ctr > 10 Then 'times before 24, 32, 41 updates per sec for 1,000 generations Header_Set 'times w ctr 36, 47, 28 using counter ' Reset Header_Set_Ctr ' End If
Update Tests with Without counter (remmed out as above) - 640X480 screen
Appropriate Pointers = 55
No pointers = 41
All Pointers = 34
Update Tests with With counter (un remmed)
Appropriate Pointers = 61 10%
No pointers = 47 13%
All Pointers = 35 3%
======================================================
"Oil prices have fallen lately.
We include this news for the benefit of gas stations,
which otherwise wouldn't learn of it for six months."
William D. Tammeus
======================================================
Leave a comment:
-
And the final thing is ... I'm just having fun. If I wasn't playing here I'd just be sitting around watching tv or {eew} reading books or some other equally even more useless endeavor.
Just having fun.
Leave a comment:
-
Originally posted by John Gleason View PostI looked at the Life code and had this thought: if you update the title information less frequently, you will see a speed improvement. So if you don't mind updating the title every say 10 generations, you might get ~14% speed improvement like I did.
From a deeply distant black void of a vacuum came:
I'll be honest up front, I have NOT looked at the code in question.
But from that vacuum I have to ask: What kind of application NEEDS to read the timer so often one would even care about the best way to do so? Or so often that performance is impacted?
Seems to me instead of reading the timer a program should be DOING whatever it is it's supposed to do instead of worrying about what time it is.
Paul said:
Gösta,
mine is a 1.9GHz Athlon.
The important result is that it only takes a few microseconds to read the TIMER. You're reading it hundreds of times a second so the total time spent reading the timer is under 0.001s for every 1 second that the program runs. If you're after significant savings in time then you need to look elsewhere because reading the TIMER is not taking up very much time at all.
Paul.
Another is I'll try to implement your timing method just to see how much difference it might actually make. If it does improve performance significantly, cool. If it doesn't, then we'll know. One thing neat about this program is it's so repetitively CPU intensive over long periods, it's relatively easy to test different methods (see Pointers thread).
Another is, I think other PB'ers are benefitting as well, just by lurking, especially the less, aaahhh, experienced like myself.
And the final thing is ... I'm just having fun. If I wasn't playing here I'd just be sitting around watching tv or {eew} reading books or some other equally even more useless endeavor.
=======================================
"Looking foolish does the spirit good."
John Updike
=======================================
(Makes me laugh too)
Leave a comment:
-
I looked at the Life code and had this thought: if you update the title information less frequently, you will see a speed improvement. So if you don't mind updating the title every say 10 generations, you might get ~14% speed improvement like I did.
Code:'enclose Stasis & Set_Header macros thusly: LOCAL ctr3 aAS LONG INCR ctr3 IF ctr3 = 10 THEN Stasis Set_Header ctr3 = 0 END IF 'and down in the Set_Header macro make: Generations = Generations + 10 '10 here is to be equal to ctr3 IF value
Leave a comment:
-
I'll be honest up front, I have NOT looked at the code in question.
But from that vacuum I have to ask: What kind of application NEEDS to read the timer so often one would even care about the best way to do so? Or so often that performance is impacted?
Seems to me instead of reading the timer a program should be DOING whatever it is it's supposed to do instead of worrying about what time it is.
Reminds me of employees whose top job priority is checking to see if it's lunchtime yet.
Leave a comment:
-
Gösta,
mine is a 1.9GHz Athlon.
The important result is that it only takes a few microseconds to read the TIMER. You're reading it hundreds of times a second so the total time spent reading the timer is under 0.001s for every 1 second that the program runs. If you're after significant savings in time then you need to look elsewhere because reading the TIMER is not taking up very much time at all.
Paul.
Leave a comment:
-
Originally posted by Paul Dixon View PostGösta,
I get
Code:1609.6884ms 1349.4648ms
I can now see that your PC would give 2.6us with TIMER and is no longer in need of winding up!
Paul.Code:'My results with Dave's Code 2667.1596ms 340.6663ms 'Paul's results 1609.6884ms 1349.4648ms
==================================
"If you are going through hell,
keep going."
Sir Winston Churchill (1874-1965)
==================================
Leave a comment:
-
Gösta,
I get
Code:1609.6884ms 1349.4648ms
I can now see that your PC would give 2.6us with TIMER and is no longer in need of winding up!
Paul.
Leave a comment:
-
Originally posted by Paul Dixon View PostGösta,
do you really mean 2.6ms (0.0026 seconds) or do you mean 2.6us (0.0000026 seconds).
If it's the first then I think your PC needs winding up!
The second one is more likely and 2.6us called a few hundred times a second is still well under 0.1% of the CPU time so it should be acceptable.
Paul.
Leave a comment:
-
Gösta,
How that compares to Paul's 1.6ms & my 2.6ms is for you to tell us/me.
Paul.
Leave a comment:
-
Dave,
The results of your test are:
2667.1596ms
340.6663ms
How that compares to Paul's 1.6ms & my 2.6ms is for you to tell us/me.
Code used:'Code:#Compile Exe #Register None #Dim All #Tools Off %NOMMIDS = 1 %NOGDI = 1 #Include "WIN32API.INC" '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Global qFreq, qOverhead, qStart, qStop As Quad Global f As String Macro InitializeTimer f = "#####.####" QueryPerformanceFrequency qFreq QueryPerformanceCounter qStart ' Intel suggestion. First use may be suspect QueryPerformanceCounter qStart ' So, wack it twice <smile> QueryPerformanceCounter qStop qOverhead = qStop - qStart ' Relatively small End Macro Macro StartTimer = QueryPerformanceCounter qStart Macro StopTimer = QueryPerformanceCounter qStop Macro sTimeTaken = Using$(f,(qStop - qStart - qOverhead)*1000/qFreq) + "ms" Macro nTimeTaken = (qStop - qStart - qOverhead)*1000/qFreq '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Function PBMain() As Long Local i As Long, x As Double, qCount As Quad, s$ InitializeTimer StartTimer For i = 1 To 1000000 x = Timer ' in seconds Next StopTimer s$ = sTimeTaken & $CrLf StartTimer For i = 1 To 1000000 QueryPerformanceCounter qCount x = qCount/qFreq ' in seconds Next StopTimer MsgBox sTimeTaken s$ = s$ & sTimeTaken ClipBoard Set Text s$ To i End Function'
Leave a comment:
-
Gösta,
do you really mean 2.6ms (0.0026 seconds) or do you mean 2.6us (0.0000026 seconds).
If it's the first then I think your PC needs winding up!
The second one is more likely and 2.6us called a few hundred times a second is still well under 0.1% of the CPU time so it should be acceptable.
Paul.
Leave a comment:
-
Originally posted by Paul Dixon View PostWhy would you think that?Have you tested it?
While TIMER isn't the faster of functions out there it still takes only 1.6micro seconds to run on my slow PC.
'Code:PBWin 9.00 - WinApi 05/2008 - XP Pro SP3 #Compile Exe #Dim All #Include "WIN32API.INC" #Include "COMDLG32.INC" Function PBMain Local k,b As Ext Local limit, r As Long limit&=1000000 k=Timer For r& = 1 To limit& b=Timer Next k=(Timer-k)/limit& * 1000000 ? Using$("Time per TIMER call= #.# 'micro seconds'", k) End Function '
Last edited by Gösta H. Lovgren-2; 9 Nov 2008, 08:05 AM.
Leave a comment:
-
There are many ways to do timings.
This one will run in the background using almost no CPU time but the timer will increment every millisecond and is accessed as fast as reading a global variable, i.e. very fast.
Code:$INCLUDE "WIN32API.INC" GLOBAL MyGlobalTimer AS LONG FUNCTION TimerUpdate ( BYVAL uID AS LONG, BYVAL uMsg AS LONG, _ BYVAL dwUser AS LONG, BYVAL dw1 AS LONG, BYVAL dw2 AS LONG) AS LONG 'this is the routine that is run everytime the timer triggers 'we just increment our global timer variable INCR MyGlobalTimer END FUNCTION FUNCTION WINMAIN (BYVAL hInstance AS LONG, _ BYVAL hPrevInstance AS LONG, _ BYVAL lpCmdLine AS ASCIIZ PTR, _ BYVAL iCmdShow AS LONG) AS LONG 'start the timer '1=milliseconds between triggers, 0=maximum timer resolution, TimerUpdate=the routine to call TimerHandle& = timeSetEvent ( BYVAL 1, BYVAL 0, CODEPTR(TimerUpdate), BYVAL 0&, BYVAL %TIME_PERIODIC) PRINT "press a key to end." DO LOCATE 10,10 PRINT "Time=";FORMAT$(MyGlobalTimer/1000,"#######.###");"secs." SLEEP 1 LOOP UNTIL INSTAT 'stop the timer before exit timeKillEvent TimerHandle& END FUNCTION
Leave a comment:
-
Gösta, I haven't been looking at Gary's code or yours as I've been busy on other things but I was drawn to this thread by virtue of its title.
Since I haven't been looking what I am about to say may be irrelevant so, obviously, ignore if so.
Since, from PB documentation, the resolution of Timer is about 1/100 of a second on NT-based platforms, or 1/18th of a second on earlier platforms, "Timer is called hundreds of times a second" will yield the same value within the resolution.
Anyway, that may be irrelevant.
With regard to the time spent calling Timer another way of getting elapsed time is to use QueryPerformanceCounter.
The following compares the two approaches. I'm using x as Double but note that tmr and so on in Life uses Longs.
Using QueryPerformanceCounter is about 6 times faster.
Code:#COMPILE EXE #Register None #Dim All #TOOLS OFF %NOMMIDS = 1 %NOGDI = 1 #Include "WIN32API.INC" '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Global qFreq, qOverhead, qStart, qStop As Quad Global f As String Macro InitializeTimer f = "#####.####" QueryPerformanceFrequency qFreq QueryPerformanceCounter qStart ' Intel suggestion. First use may be suspect QueryPerformanceCounter qStart ' So, wack it twice <smile> QueryPerformanceCounter qStop qOverhead = qStop - qStart ' Relatively small End Macro Macro StartTimer = QueryPerformanceCounter qStart Macro StopTimer = QueryPerformanceCounter qStop Macro sTimeTaken = Using$(f,(qStop - qStart - qOverhead)*1000/qFreq) + "ms" Macro nTimeTaken = (qStop - qStart - qOverhead)*1000/qFreq '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Function PBMain() As Long Local i As Long, x As Double, qCount As Quad InitializeTimer StartTimer For i = 1 To 1000000 x = Timer ' in seconds Next StopTimer MsgBox sTimeTaken StartTimer For i = 1 To 1000000 QueryPerformanceCounter qCount x = qCount/qFreq ' in seconds Next StopTimer MsgBox sTimeTaken End Function
Leave a comment:
-
Dale,
there's no reason from the CPU's point of view that the speed of the comparison should be different.
If the compiler does its job then the 2 comparisons will take the exact same time and use the same code except for the choice of which one conditional branch instruction to use at the end. The CPU has lots of conditional branch instructions to choose from, they all run at the same speed.
You CAN speed up that code by using LONGs instead of DWORDs.
Mel,
I think you misunderstand.
There's no need for a FOR/NEXT loop to be a different speed counting up or down.
In cases where the loop counter is not referenced within the loop then the compiler will optimise the counter to count down to zero which saves on one compare instruction as the zero flag will be set already by the update of the loop counter and the loop can exit on that condition.
This isn't done if you specify a terminal loop count of zero, only if the compiler sees the shortcut for itself.
Paul.
Leave a comment:
-
It's always been my understanding calls to Timer are "expensive" (CPU time eaters)
While TIMER isn't the faster of functions out there it still takes only 1.6micro seconds to run on my slow PC.
Code:'PBCC5.0 program FUNCTION PBMAIN() AS LONG LOCAL k,b AS EXT limit&=1000000 k=TIMER FOR r& = 1 TO limit& b=TIMER NEXT k=(TIMER-k)/limit& * 1000000 PRINT "Time per TIMER call=";k; "micro seconds" WAITKEY$ END FUNCTION
Leave a comment:
-
I haven't tried it but....
As I understand it, For/Next loops are slightly faster using STEP -X. IOW:
for x = 100 to 1 step -1
is slightly faster than
for x = 1 to 100
So changing your code to:
Faux_Timer_Ctr = 101 ' Somewhere in your program
Decr Faux_Timer_Ctr
If Faux_Timer_Ctr = 0 Then
...
...
MIGHT speed things up a bit. Then again, it might not.
Leave a comment:
Leave a comment: