• QueryPerformanceCounter (VB6)

    Author
    Topic
    #417396

    Hi

    I am using the QueryPerformanceCounter to time a piece of code. I need timing in microseconds.

    My code compiles okay but the end result is 0 I think this is because my function is not accessing the kernel32.dll and so is not passing any value in the parameter. Do I have to do anything other than the Declare Function statements

    This is what the code looks like at present

    Option Explicit

    Private Declare Function QueryPerformanceCounter Lib “KERNEL32” _
    (lpPerformanceCount As Currency) As Long
    Private Declare Function QueryPerformanceFrequency Lib “KERNEL32” _
    (lpPerformanceCount As Currency) As Long

    Sub BinarySearch()

    Dim sec As Currency
    Dim secOut As Currency

    ProfileStart sec

    Do the Binary Search

    ProfileStop sec, secOut

    End Sub

    Sub ProfileStart(secStart As Currency)

    Dim secFreq As Currency

    If secFreq = 0 Then QueryPerformanceFrequency secFreq
    QueryPerformanceCounter secStart

    End Sub

    Sub ProfileStop(secStart As Currency, secTiming As Currency)

    Dim secFreq As Currency

    QueryPerformanceCounter secTiming
    If secFreq = 0 Then
    secTiming = 0 ‘Handle old system with no high-resolution timer
    Else
    secTiming = (secTiming – secStart) / secFreq
    End If

    lblCheck.Visible = True
    lblCheck.Caption = secTiming

    End Sub

    Now the code looks okay to me (famous last words) So what am I missing please?

    Viewing 1 reply thread
    Author
    Replies
    • #936416

      I don’t understand the role of secFreq in ProfileStart and ProfileStop. In neither procedure, a value is assigned to secFreq, so it is always 0. As a consequence, secTiming is always set to 0. What was secFreq intended to do?

    • #936417

      Does this do what you want?

      Private Declare Function QueryPerformanceCounter Lib “KERNEL32” _
      (lpPerformanceCount As Currency) As Long
      Private Declare Function QueryPerformanceFrequency Lib “KERNEL32” _
      (lpPerformanceCount As Currency) As Long

      Sub BinarySearch()
      Dim sec As Currency
      ProfileStart sec
      ‘ do the binary search here
      ProfileStop sec
      End Sub

      Sub ProfileStart(secStart As Currency)
      QueryPerformanceCounter secStart
      End Sub

      Sub ProfileStop(secStart As Currency)
      Dim secTiming As Currency
      Dim secFreq As Currency

      QueryPerformanceFrequency secFreq
      QueryPerformanceCounter secTiming

      If Not secFreq = 0 Then
      secTiming = (secTiming – secStart) / secFreq
      End If

      lblCheck.Visible = True
      lblCheck.Caption = secTiming
      End Sub

      • #936513

        Almost!

        There is an issue with

        Sub ProfileStop(secStart As Currency)
        Dim secTiming As Currency
        Dim secFreq As Currency

        QueryPerformanceFrequency secFreq
        QueryPerformanceCounter secTiming

        If Not secFreq = 0 Then
        secTiming = (secTiming – secStart) / secFreq
        End If

        lblCheck.Visible = True
        lblCheck.Caption = secTiming
        End Sub

        I have used lblCheck to find out that secFreq, secTiming and secStart all contain values at the point before the If Statement but the code still returns zero.

        Further experimenting…

        secTiming = (secTiming – secStart) / secFreq ‘used with or without IF statement
        lblCheck.Caption = secTiming ‘returns zero

        but
        lblCheck.Caption = (secTiming – secStart) / secFreq ‘returns a result

        Seems very odd.

        • #936556

          Sorry, no idea. It works for me, and I see no reason why

          secTiming = (secTiming – secStart) / secFreq
          lblCheck.Caption = secTiming

          and

          lblCheck.Caption = (secTiming – secStart) / secFreq

          should produce different results.

          • #936639

            Hi

            A bit more investigation. I now have amended the code and it is working.

            Still don’t understanding what is happening. But the issue seems to be something to do with formatting. The binary search is completed very quickly – around 15 microseconds.

            Code as previously written returns seconds. Amended code to convert to microseconds

            If Not secFreq = 0 Then
            secTiming = ((secTiming – secStart) / secFreq) * 1000000
            End If

            Which returns a result to to four decimal places

            Whereas using lblCheck.Caption = ((secTiming – secStart) / secFreq) * 1000000
            returns the same result only to around 15 decimal places

            Without *1000000
            lblCheck.Caption = (secTiming – secStart) / secFreq
            returns the result to 15 decimal places to the power of minus 5

            So as SecTiming is Currency format
            does using

            secTiming = (secTiming – secStart) / secFreq

            return a number to secTiming which too small for it to display?

            Anyway the code works. Once again thanks very much for all your help.

            • #936641

              Currency format stores numbers with 4 decimal places, so that explains your result. If you set the label directly, the result of the division is a double precision floating point number (with 15 decimals), it is not converted into currency (with 4 decimals).

              (Timing a an action that only takes 15 microseconds doesn’t seem very useful. The overhead must be much more than 15 microseconds.)

    Viewing 1 reply thread
    Reply To: QueryPerformanceCounter (VB6)

    You can use BBCodes to format your content.
    Your account can't use all available BBCodes, they will be stripped before saving.

    Your information: