Post

 Resources 

Console

Home | Profile | Active Topics | Members | Search | FAQ
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 VBGamer
 VBGamer
 FPS Counter
 New Topic  Reply to Topic
 Printer Friendly
Previous Page | Next Page
Author Previous Topic Topic Next Topic
Page: of 3

Lachlan87
Moderator

USA
160 Posts

Posted - Jun 11 2004 :  3:00:28 PM  Show Profile  Reply with Quote
timeGetTime seems to work fine, but maybe I'll switch to QueryPerformanceCounter anyway, if it's that much faster. What is really strange to me is how much of a difference there is between GetTickCount and timeGetTime. I'm only drawing a handful of images, and I have a pretty powerful computer by many peoples standards (the only reason timeGetTime gives me 85 is because that's what my monitors refresh rate is set at). It seems to me even if it was a congested thread, it wouldn't make that much of a difference. The cpu usage is the same no matter which I use. . . maybe I'll try it on a different computer and see what happens.

Go to Top of Page

Eric Coleman
Gladiator

USA
811 Posts

Posted - Jun 11 2004 :  5:06:49 PM  Show Profile  Visit Eric Coleman's Homepage  Reply with Quote
If "GetTickCount" returns "ticks", what exactly are the time units of a single tick? It might be that a "tick" is just an incrimented number whenever the system timer is updated. The discrepency that you experienced is just really odd, and I can't think of any other way to explain it.

The precision of timeGetTime is on the order of 10 ms, which is 1/100th of a second. Considering that a game running at 60 FPS must complete a single frame in 1/60th of a second, then for timing purposes (animations and stuff) timeGetTime isn't exactly the best thing to use because the precision of the time step is relatively small compared with the size of the frame time step.
Go to Top of Page

Lachlan87
Moderator

USA
160 Posts

Posted - Jun 11 2004 :  6:18:48 PM  Show Profile  Reply with Quote
According to MSDN, GetTickCount's "return value is the number of milliseconds that have elapsed since the system was started."

Sounds the same as timeGetTime to me. . .

Tested it on my brother's computer, and had the same result: 85 FPS for timeGetTime, 20 FPS for GetTickCount. Has anyone else noticed this with their games?

Edited by - Lachlan87 on Jun 11 2004 6:38:02 PM
Go to Top of Page

Eric Coleman
Gladiator

USA
811 Posts

Posted - Jun 11 2004 :  6:43:12 PM  Show Profile  Visit Eric Coleman's Homepage  Reply with Quote
Is the FPS value when using GetTickCount wrong or does it slow down the game to 20 FPS? I only ever used QueryPerformanceCounter or timeGetTime, so I never noticed the getTickCount problem.
Go to Top of Page

game_maker
Knave

Saudi Arabia
83 Posts

Posted - Jun 11 2004 :  6:51:42 PM  Show Profile  Visit game_maker's Homepage  Reply with Quote
I have just tested this code

  
Option Explicit
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long
Dim numFrames1 As Long, FirstTime1 As Long, FPS1 As Long
Dim numFrames2 As Long, FirstTime2 As Long, FPS2 As Long
  
Private Sub Form_Load()  
Me.Show  
Do
numFrames1 = numFrames1 + 1  
        If timeGetTime - FirstTime1 > 999 Then
            FPS1 = numFrames1  
            FirstTime1 = timeGetTime  
            numFrames1 = 0  
        End If
numFrames2 = numFrames2 + 1  
        If Sgn(GetTickCount - FirstTime2 - 999) + 1 Then
            FPS2 = numFrames2  
            FirstTime2 = GetTickCount  
            numFrames2 = 0  
        End If
  
DoEvents  
  
Me.Caption = "FPS1 = " & FPS1 & "     " & "FPS2 = " & FPS2  
DoEvents  
Loop
End Sub
  


they are 100% same ,, i.e. as Eric said your test is odd
Go to Top of Page

Eric Coleman
Gladiator

USA
811 Posts

Posted - Jun 11 2004 :  7:28:59 PM  Show Profile  Visit Eric Coleman's Homepage  Reply with Quote
Here is some more code. Just copy and paste this on a form named "form1" with a command button named "command1"

This code tests the resolution of the different timers. It calls the time function, and then repeatedly calls the time function untill the returned value changes. The difference between the two values shows the precision of the timer function. The Timer function seems to be slightly more precise, but less accurate on my system. It is more prone to fluctuations returning either it's time step or it's time step times 2.

  
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long
  
  
Private Sub Command1_Click()  
  
Form1.Cls  
Form1.CurrentX = 0: Form1.CurrentY = 0  
  
Dim s As Long, t As Long
Dim u As Single, v As Single
Dim Freq As Currency, x As Currency, y As Currency, sngResult As Single
  
  
s = GetTickCount()  
Do
    t = GetTickCount()  
    If t - s > 0 Then Exit Do
Loop
Form1.Print (t - s) / 1000 'convert from milliseconds to seconds  
  
  
s = timeGetTime()  
Do
    t = timeGetTime()  
    If t - s > 0 Then Exit Do
Loop
Form1.Print (t - s) / 1000 'convert from milliseconds to seconds.  
  
  
u = Timer  
Do
    v = Timer  
    If v - u > 0 Then Exit Do
Loop
Form1.Print (v - u) 'already in seconds.  
  
  
QueryPerformanceFrequency Freq  
QueryPerformanceCounter x  
Do
    QueryPerformanceCounter y  
    If y - x > 0 Then Exit Do
Loop
sngResult = (y - x) / Freq  
Form1.Print Format$(sngResult, " 0.000000000000")  
  
End Sub
  
  


after writing this I found the following from microsoft, it seems they did the same thing I just did, http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q172/3/38.asp&NoWebContent=1

Go to Top of Page

Lachlan87
Moderator

USA
160 Posts

Posted - Jun 12 2004 :  10:03:10 AM  Show Profile  Reply with Quote
One thing I forgot to mention, and may be key to my problem, is that I am using VB.Net, which doesn't always get along with the windows API so well. game_maker's code gives me about 1187 for both values when I put it in VB6--but when I convert it to VB.Net like so:

  
    Private Declare Auto Function timeGetTime Lib "winmm.dll" () As Long
    Private Declare Auto Function GetTickCount Lib "kernel32" () As Long
    Dim numFrames1 As Long, FirstTime1 As Long, FPS1 As Long
    Dim numFrames2 As Long, FirstTime2 As Long, FPS2 As Long
  
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load  
        Me.Show()  
        Do
            numFrames1 = numFrames1 + 1  
            If timeGetTime - FirstTime1 > 999 Then
                FPS1 = numFrames1  
                FirstTime1 = timeGetTime  
                numFrames1 = 0  
            End If
            numFrames2 = numFrames2 + 1  
            If Math.Sign(GetTickCount - FirstTime2 - 999) + 1 Then
                FPS2 = numFrames2  
                FirstTime2 = GetTickCount  
                numFrames2 = 0  
            End If
  
            Application.DoEvents()  
  
            Me.Text = "FPS1 = " & FPS1 & "     " & "FPS2 = " & FPS2  
            Application.DoEvents()  
        Loop
    End Sub
  
  


I get about 85203 for timeGetTime and about 21843 for GetTickCount.

It doesn't make any sense to me. I would instinctively guess that VB.Net wasn't converting the data types correctly, but since both timeGetTime and GetTickCount return a Long, it ought to make the same error on both, if it truely was a conversion error. Besides, VB.Net's long can hold much greater values that VB6's, so it seems like there would be no problem.

But that was my reasoning using logic, which doesn't apply when we're working with a product made by Microsoft. I changed GetTickCount to As Integer, and Voila! Now they both return 85 thousand. For some perverted reason GetTickCount wouldn't convert right and timeGetTime would.

But that still leaves the question: Why are the values I get in VB.Net so wildy different than the values I get in VB6? I can't decide if VB.Net is too high, or if VB6 is too low, but they can't both be right! Can they? When logic as I understand it fails, I start to wonder . . .

And just to confuse things a little more, Eric's VB6 code returns the same values for timeGetTime and GetTickCount as my VB.Net verison of his code---without changing any longs to integers!!
Go to Top of Page

Sr. Guapo
Swordmaster

USA
272 Posts

Posted - Jun 12 2004 :  10:43:34 AM  Show Profile  Reply with Quote
It is possible that DoEvents in VB6 doesn't take as long as Application.DoEvents() in VB.NET... IT doesn't seem likely, but I don't know what else it would be...

Edited by - Sr. Guapo on Jun 12 2004 10:57:50 AM
Go to Top of Page

Lachlan87
Moderator

USA
160 Posts

Posted - Jun 12 2004 :  1:37:40 PM  Show Profile  Reply with Quote
Ok, I think I finally figured it out. First, changing the title bar's text makes for quite a speed hit, so I removed that. That made both versions much faster, but vb6 was still lagging behind by about 100,000. So I did a rather sloppy test(Hopefully Almar will do a better one for persistent realities), and it seems as though vb.net can call timeGetTime and GetTickCount faster than VB6. My very unprofessional testing code is below.

VB6 Version:
  
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long
  
Private Sub Command1_Click()  
Dim firstTime As Long
Dim frames As Long
  
frames = 0  
  
firstTime = GetTickCount  
  
Do Until GetTickCount - firstTime > 999  
frames = frames + 1  
Loop
  
Form1.Print frames  
  
frames = 0  
  
firstTime = timeGetTime  
  
Do Until timeGetTime - firstTime > 999  
frames = frames + 1  
Loop
  
Form1.Print frames  
  
  
End Sub
  
  

VB.Net Version:
  
    Private Declare Auto Function timeGetTime Lib "winmm.dll" () As Long
    Private Declare Auto Function GetTickCount Lib "kernel32" () As Integer
  
  
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click  
  
        Dim firstTime As Long
        Dim frames As Long
  
        frames = 0  
  
        firstTime = GetTickCount  
  
        Do Until GetTickCount - firstTime > 999  
            frames = frames + 1  
        Loop
  
        Label1.Text += frames.ToString & vbCrLf  
  
        frames = 0  
  
        firstTime = timeGetTime  
  
        Do Until timeGetTime - firstTime > 999  
            frames = frames + 1  
        Loop
  
        Label1.Text += frames.ToString  
  
  
  
    End Sub
  


My results were:
VB6:
7046999 - GetTickCount
5660505 - timeGetTime

VB.Net
8798485 - GetTickCount
6452133 - timeGetTime

It is my current opinion that this accounts for the speed difference---but I know I my tests were not kosher. Maybe I'll do the job properly later with QueryPerformance counter.

BTW, I did try removing the DoEvents stuff, but it didn't account for the gap. Sorry if I'm boring you guys---I find this stuff interesting!

Edited by - Lachlan87 on Jun 12 2004 1:41:39 PM
Go to Top of Page

Eric Coleman
Gladiator

USA
811 Posts

Posted - Jun 12 2004 :  4:34:17 PM  Show Profile  Visit Eric Coleman's Homepage  Reply with Quote
I'm surprised that code even works at all for you. A LONG data type in VB6 isn't the same thing as a LONG data type in VB.NET. When declaring windows API calls in VB.NET you have to make sure the data type size is the same as what's returned and what's used as parameters, otherwise you'll be reading from memory that you're not supposed to, and VB.NET will convert stuff that it shouldn't be converting.
Go to Top of Page

game_maker
Knave

Saudi Arabia
83 Posts

Posted - Jun 12 2004 :  4:48:56 PM  Show Profile  Visit game_maker's Homepage  Reply with Quote
great ^^

I think you missed some small thing in your code becouse you calculate (timeGetTime - firstTime > 999 ) and frames = frames + 1 and the loop circle
all of these takes time (ns),,, so it's not exactly what we looking for

I mean :

  
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long
  
Private Sub Command1_Click()  
Dim lastTime As Single
Dim firstTime As Long
Dim x1 As Long, x2 As Long
Dim frames As Long
Dim Count1 As Long
  
'--------Speed of one count
  
firstTime = GetTickCount  
Count1 = GetTickCount - firstTime  
  
'--------Speed of the loop
firstTime = GetTickCount  
lastTime = firstTime  
  
Do Until lastTime - firstTime > 999  
lastTime = lastTime + 1  
Loop
  
lastTime = GetTickCount - firstTime - Count1  
  
Form1.Print lastTime  
'---------
frames = 0  
  
firstTime = GetTickCount  
  
Do Until GetTickCount - firstTime > 999  
frames = frames + 1  
Loop
  
x1 = frames - lastTime  
  
Form1.Print x1  
'---------
  
frames = 0  
  
firstTime = timeGetTime  
  
Do Until timeGetTime - firstTime > 999  
frames = frames + 1  
Loop
  
x2 = frames - lastTime  
  
Form1.Print x2  
  
Form1.Print (x1 - x2) / x2 * 100 & " %"  
  
End Sub
  


This gives you exactly 100% FPS ( I think )

By the way this is not frame rate this is CPS (Calls / Second) witch we wan't to find (the speed of calling a function )

I got (VB.6) :
0 *
3440201
3205927
7.307%

this means to me GettickCount is faster to call

* : (my added code is not important here with fast functions and fast computers )
It's important to report the bug you find to microsoft

Edited by - game_maker on Jun 12 2004 5:01:51 PM
Go to Top of Page

Lachlan87
Moderator

USA
160 Posts

Posted - Jun 12 2004 :  10:14:41 PM  Show Profile  Reply with Quote
quote:
A LONG data type in VB6 isn't the same thing as a LONG data type in VB.NET


That I understood. I had thought that VB.Net performed the conversions automatically, but I guess I must have been thinking of the other way of using the windows API (dllImport or something like that).

game_maker: I realize my "test" was backwards and not particularly accurate, but even still, I thought it was safe to infer that GetTickCount was faster.

Oh, well. At least my problem was fixed, and I managed to learn some things. . . but like Eric said, I still wonder why timeGetTime and other API functions work if VB.Net isn't auto converting things.
Go to Top of Page

Sr. Guapo
Swordmaster

USA
272 Posts

Posted - Jun 12 2004 :  11:08:47 PM  Show Profile  Reply with Quote
quote:
I still wonder why timeGetTime and other API functions work if VB.Net isn't auto converting things.


Maybe they do that now in VB .NET to discourage the use of variants... Dunno...

What if you defined the GetTickCount as an "Int32" in .NET, I think that is all that a long is, a 32 bit integer. Correct me if I'm wrong.
Go to Top of Page

game_maker
Knave

Saudi Arabia
83 Posts

Posted - Jun 13 2004 :  12:35:04 AM  Show Profile  Visit game_maker's Homepage  Reply with Quote
in VB.6 :

Long is 4 byte

so it's :

2^(8 * 4) = 4294967296

we dived it by 2 (to get plus and minus numbers)

2^(8 * 4) / 2 =

2147483648 to 2147483648

we save one bit to determine (minus or plus sign)

-2147483648 to 2147483647

we need to find the same properties in VB.Net :

in VB.Net

Integer here defined as 4 byte and accept minus so it's the same definition in VB.6 Longs ... as you did !!! why microsoft did this ,,, if the have to change something then they should define something that have (integers in 8 bytes) and not changing everything

and for Long it's = 8 byte as Double in vb.6

and the definition is not stable ,,it depens on wither it's 32-bit or 64-bit
Go to Top of Page

Dan
Squire

United Kingdom
29 Posts

Posted - Jun 13 2004 :  03:54:07 AM  Show Profile  Visit Dan's Homepage  Reply with Quote
quote:
Integer here defined as 4 byte and accept minus so it's the same definition in VB.6 Longs ... as you did !!! why microsoft did this ,,, if the have to change something then they should define something that have (integers in 8 bytes) and not changing everything


I think it has somthing to do with the fact the .NET framework is made up of the supposed 'Best bits' of VB and C. I believe C#'s Int/long variable types are 4 / 8 bytes respectivly. so it came to a toss up between who keeps the type definitions and C# won... makes sense really - Its easier to put a small parcel in a a big box, a wee bit trickier to do the reverse :)


Go to Top of Page
Page: of 3 Previous Topic Topic Next Topic  
Previous Page | Next Page
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
VBGamer © Go To Top Of Page
This page was generated in 0.41 seconds. Snitz Forums 2000

Copyright © 2002 - 2004 Eric Coleman, Peter Kuchnio , et. al.