Como utilizar QueryPerformanceCounter para código de tempo

Artigo: 172338 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Nesta página

Sumário

Quando o tempo código para identificar congestionamentos de desempenho, que pretende utilizar o temporizador de resolução mais elevado que o sistema tem para oferecer. Este artigo descreve como utilizar a função QueryPerformanceCounter código de aplicação de tempo.

Mais Informação

Vários temporizadores de exactidão diferente são oferecidos pelo sistema operativo:
Function                 Units                      Resolution
---------------------------------------------------------------------------
Now, Time, Timer         seconds                    1 second
GetTickCount             milliseconds               approx. 10 ms
TimeGetTime              milliseconds               approx. 10 ms
QueryPerformanceCounter  QueryPerformanceFrequency  same
				
se o sistema suporta um contador de alta resolução, pode utilizar o QueryPerformanceCounter e QueryPerformanceFrequency fazer temporizações de alta resolução.

O código de exemplo seguinte compara os vários contadores:

AVISO: A UTILIZAÇÃO POR SI O CÓDIGO FORNECIDO NESTE ARTIGO É DA RESPONSABILIDADE DO UTILIZADOR. A Microsoft fornece este código "tal como está" sem garantias de qualquer tipo, expressas ou implícita, incluindo sem limitação as garantias implícitas de comercialização e/ou adequação a um fim específico.

Procedimentos passo a passo

  1. Introduza o código seguinte para um módulo. Se introduzir numa classe, formulário ou módulo de relatório, efectue as declarações privada.
           Option Explicit
    
          Declare Function QueryPerformanceCounter Lib "Kernel32" _
                                     (X As Currency) As Boolean
          Declare Function QueryPerformanceFrequency Lib "Kernel32" _
                                     (X As Currency) As Boolean
          Declare Function GetTickCount Lib "Kernel32" () As Long
          Declare Function timeGetTime Lib "winmm.dll" () As Long
    
          Sub Test_Timers()
          Dim Ctr1 As Currency, Ctr2 As Currency, Freq As Currency
          Dim Count1 As Long, Count2 As Long, Loops As Long
          '
          ' Time QueryPerformanceCounter
          '
            If QueryPerformanceCounter(Ctr1) Then
              QueryPerformanceCounter Ctr2
              Debug.Print "Start Value: "; Format$(Ctr1, "0.0000")
              Debug.Print "End Value: "; Format$(Ctr2, "0.0000")
              QueryPerformanceFrequency Freq
              Debug.Print "QueryPerformanceCounter minimum resolution: 1/" & _
                          Freq * 10000; " sec"
              Debug.Print "API Overhead: "; (Ctr2 - Ctr1) / Freq; "seconds"
            Else
              Debug.Print "High-resolution counter not supported."
            End If
          '
          ' Time GetTickCount
          '
            Debug.Print
            Loops = 0
            Count1 = GetTickCount()
            Do
              Count2 = GetTickCount()
              Loops = Loops + 1
            Loop Until Count1 <> Count2
            Debug.Print "GetTickCount minimum resolution: "; _
                        (Count2 - Count1); "ms"
            Debug.Print "Took"; Loops; "loops"
          '
          ' Time timeGetTime
          '
            Debug.Print
            Loops = 0
            Count1 = timeGetTime()
            Do
              Count2 = timeGetTime()
              Loops = Loops + 1
            Loop Until Count1 <> Count2
            Debug.Print "timeGetTime minimum resolution: "; _
                        (Count2 - Count1); "ms"
            Debug.Print "Took"; Loops; "loops"
          End Sub
    						
  2. Execute a função da janela Immediate/Debug. A saída deverá ser semelhante à seguinte:
    Inicie o valor: 3516284.3498
    Valor final: 3516284.3521
    Resolução mínima QueryPerformanceCounter: 1/1193182 seg
    Custos gerais de API: 1.92761875388667E - seconds 05

    Resolução mínima ObterContagemMarcaEscala: 10 ms
    Demorou 650 ciclos

    resolução mínima timeGetTime: 10 ms
    Demorou 1565 ciclos
Várias instruções executar antes ou ObterContagemMarcaEscala timeGetTime registar uma alteração. O número real de ciclos irá variar consoante as tarefas em segundo plano que está a executar o sistema operativo.

Por outro lado, QueryPerformanceCounter altera o valor entre chamadas de API sucessivas, indicando a respectiva utilidade em tempo de alta resolução. Neste caso é a resolução na ordem de um microsecond. Uma vez que a resolução é dependente do sistema, existem não unidades padrão-medidas. Tem de dividir a diferença por QueryPerformanceFrequency para determinar que o número de segundos decorrido. No caso, a sobrecarga para apenas accione a API é cerca 19 microssegundos. Isto teria de ser subtraído ao tempo outro código da seguinte forma:
   Private Sub Time_Addition()
   Dim Ctr1 As Currency, Ctr2 As Currency, Freq As Currency
   Dim Overhead As Currency, A As Long, I As Long
     QueryPerformanceFrequency Freq
     QueryPerformanceCounter Ctr1
     QueryPerformanceCounter Ctr2
     Overhead = Ctr2 - Ctr1        ' determine API overhead
     QueryPerformanceCounter Ctr1  ' time loop
     For I = 1 To 100
       A = A + I
     Next I
     QueryPerformanceCounter Ctr2
     Debug.Print "("; Ctr1; "-"; Ctr2; "-"; Overhead; ") /"; Freq
     Debug.Print "100 additions took";
     Debug.Print (Ctr2 - Ctr1 - Overhead) / Freq; "seconds"
   End Sub
				
exemplo de resultado:
(3630876.6256-3630876.6388-0.0013) / 119.3182
100 adições demorou 9.97333181358753E - seconds 05
NOTA: Uma vez que as variáveis de moeda são utilizadas, os valores devolvidos são horas 10000 menos do que os contadores reais. Uma vez que o cálculo da segundos envolve uma operação de divisão, este factor é cancelada.

Referências

Microsoft Developer Network; tópicos: timeGetTime ObterContagemMarcaEscala QueryPerformanceCounter QueryPerformanceFrequency

Propriedades

Artigo: 172338 - Última revisão: sábado, 20 de Janeiro de 2007 - Revisão: 3.3
A informação contida neste artigo aplica-se a:
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Visual Basic 5.0 Learning Edition
  • Microsoft Visual Basic 6.0 Learning Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
  • Microsoft Visual Basic Control Creation Edition
  • Microsoft Visual Basic 4.0 Standard Edition
  • Microsoft Visual Basic 4.0 Professional Edition
  • Microsoft Visual Basic 4.0 32-Bit Enterprise Edition
  • Microsoft Access 2002 Standard Edition
  • Microsoft Access 2000 Standard Edition
  • Microsoft Access 97 Standard Edition
  • Microsoft Access 95 Standard Edition
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 97 Standard Edition
  • Microsoft Excel 95 Standard Edition
  • Microsoft Word 2002 Standard Edition
  • Microsoft Word 2000 Standard Edition
  • Microsoft Word 97 Standard Edition
Palavras-chave: 
kbmt kbhowto kbprogramming KB172338 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática… erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 172338

Submeter comentários