Pergunta

Em Win32, há alguma maneira de obter uma contagem de ciclo de CPU única ou algo semelhante que seria uniforme para vários processos / línguas / sistemas / etc.

Estou criando alguns arquivos de log, mas tem que produzir vários arquivos de log porque está hospedando o tempo de execução .NET, e eu gostaria de evitar chamar de um para o outro para fazer logon. Como tal, eu estava pensando que eu tinha acabado de produzir dois arquivos, combiná-los e, em seguida, classificar-los, para obter uma linha de tempo coerente, envolvendo chamadas cross-mundo.

No entanto, GetTickCount não aumenta para cada chamada, de modo que não é confiável. Existe um número melhor, para que eu recebo as chamadas na ordem certa ao classificar?


Editar : Graças a @ Greg que me colocou na pista para QueryPerformanceCounter , que fez o truque.

Foi útil?

Solução

Você pode usar o (x86 assumindo) RDTSC CPU instrução. Esta instrução dá o contador de ciclo de CPU, mas esteja ciente de que vai aumentar muito rapidamente a seu valor máximo, e depois repor a 0. Como o artigo Wikipedia menciona, você pode ser melhor fora de usar o função QueryPerformanceCounter .

Outras dicas

Heres um artigo interessante! não diz ao uso RDTSC, mas para em vez usar QueryPerformanceCounter .

Conclusão:

Usando timeGetTime() idade regular para fazer timing não é de confiança em muitos sistemas operacionais baseados no Windows porque a granularidade do sistema temporizador pode ser tão elevada como 10-15 milissegundos, o que significa que timeGetTime() só é preciso 10-15 milissegundos. [Nota que o elevados granularities ocorrer em-Based sistemas operacionais como o Windows NT, 2000 e XP. Windows 95 e 98 tendem ter muito melhor granularidade, cerca de 1-5 ms.]

No entanto, se você chamar timeBeginPeriod(1) no início do seu programa (e timeEndPeriod(1) em final), timeGetTime() geralmente se tornar preciso para 1-2 milissegundos, e irá fornecer-lhe extremamente informações cronometragem precisa.

Sleep() comporta da mesma forma; O comprimento de tempo que Sleep() realmente dorme para caminha lado a lado com o granularidade de timeGetTime(), então depois chamando timeBeginPeriod(1) uma vez, Sleep(1) irá, na verdade, para dormir 1-2 milissegundos, Sleep(2) por 2-3, e assim em (em vez de dormir em incrementos tão elevada como 10-15 ms).

Para maior sincronismo de precisão (Precisão sub-milissegundos), você vai provavelmente vai querer evitar o uso do RDTSC montagem acelerador porque é difícil calibrar ; em vez disso, o uso QueryPerformanceFrequency e QueryPerformanceCounter, que são precisos para menos de 10 microssegundos (0,00001 segundos).

Para simples momento, tanto timeGetTime e QueryPerformanceCounter funcionar bem, e QueryPerformanceCounter é obviamente mais precisos. No entanto, se você precisa fazer qualquer tipo de "cronometrada pausas"(tais como os necessários para framerate limitante), você precisa ser cuidado de sentar em uma chamada de loop QueryPerformanceCounter, esperando -lo para alcançar um determinado valor; Isso vai comer até 100% do seu processador. Em vez disso, considere um esquema híbrido, onde você chamar Sleep (1) (não se esqueça timeBeginPeriod (1) em primeiro lugar!) sempre você precisa passar mais de 1 ms de tempo, e só então entrar no QueryPerformanceCounter 100% malha -ocupado Para terminar a última <1/1000 de um segundo do atraso que você precisa. este lhe dará atrasos de ultra-precisos (com precisão de 10 microssegundos), com uso de CPU mínimo. Veja o código acima.

System.Diagnostics.Stopwatch.GetTimestamp () retornar o número de ciclo de CPU desde a origem do tempo (talvez quando o início computador, mas não tenho certeza) e eu nunca vi isso não aumentou entre 2 chamadas.

Os ciclos de CPU será específica para cada computador para que você não pode usá-lo para mesclar arquivo de log entre 2 computadores.

saída RDTSC pode depender de freqüência de clock do núcleo corrente, o que para processadores modernos não é constante nem, em uma máquina multicore, consistente.

Use a hora do sistema, e se lidar com feeds de vários sistemas usam uma fonte de tempo NTP. Você pode obter leituras de tempo consistentes de confiança que maneira; Se a sobrecarga é demais para os seus fins, usando o HPET para trabalho fora do tempo decorrido desde a leitura de tempo confiável último conhecido é melhor do que usar o HPET sozinho.

Use o GetTickCount e adicionar outro contador como você mesclar os arquivos de log. não lhe dará seqüência perfeita entre os diferentes arquivos de log, mas, pelo menos, manter todos os registros de cada arquivo na ordem correta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top