N∞kdy se stane, ₧e pot°ebujete zm∞°it jak dlouh² Φasov² ·sek ub∞hl mezi provßd∞nφm dvou Φßstφ k≤du. Pak pravd∞podobn∞ pou₧ijete standartnφ C funkci clock nebo time a zjistφte, ₧e jejich p°esnost nestojφ za nic. P°esn∞jÜφ rozliÜenφ jak sekunda zφskßte jen pomocφ funkce clock a to ne o moc. Ale nezoufejte. Existujφ funkce kterΘ umφ m∞°it p°esn∞ji.
Jednou z nich je funkce timeGetTime, kterß vracφ poΦet milisekund od startu Windows. Tato funkce je implementovßna v dll knihovn∞ winmm.dll. To znamenß, ₧e abyste ji mohli pou₧φvat musφte do svΘho programu vlo₧it hlaviΦkov² soubor mmsystem.h a lib soubor winmm.lib. V nßsledujφcφm p°ikladu pomocφ nφ zm∞°φm jak dlouho trvß provedenφ funkce printf v konzolovΘ aplikaci.
#include "stdafx.h"
#include "stdio.h"
#include <windows.h> // hlaviΦkov² soubor pro windows, aby Üel pou₧φt hlaviΦkov² soubor mmsystem.h
#include <mmsystem.h> // hlaviΦkov² soubor knihovny winmm.dll
#pragma comment(lib,"winmm.lib") // lib soubor knihovny winmm.dll
int main(int argc, char* argv[])
{
DWORD start,stop;
start = timeGetTime(); // ZaΦßtek m∞°enΘho ΦasovΘho ·seku
printf("Merena funkce printf\n");
stop = timeGetTime(); // Konec m∞°enΘho ΦasovΘho ·seku
printf("Namereny cas: %d milisekund\n",stop-start);
return 0;
}
Pokud zkusφte tento program p°elo₧it a spustit, zobrazφ vßm jak dlouho trvalo provedenφ funkce printf v milisekundßch na vaÜem poΦφtaΦi. Na mΘm ukßzal, ₧e to trvß nula milisekund, co₧ znamenß mΘn∞ ne₧ jednu milisekundu.
Tφmto postupem jsme se tedy nic nedozv∞d∞li. Chce to pou₧φt p°esn∞jÜφ funkci pro m∞°enφ Φasu. K tomu slou₧φ takzvan² Performance Counter. S nφm je ale jedna potφ₧. Musφ jej podporovat vßÜ hardware. NaÜt∞stφ lze za b∞hu programu zjistit zda jej vßÜ poΦφtaΦ podporuje. Kdy₧ zjistφte, ₧e ne m∞li by jste pou₧φt jin² zp∙sob m∞°enφ Φasu. Jß to d∞lßm tak, ₧e pokud zjistφm, ₧e nenφ podporovßn nastavφm n∞jakou prom∞nnou typu BOOL na FALSE a podle nφ pak volßm bu∩ funkce Performance Counteru nebo funkci timeGetTime. A te∩ ten sam² p°φklad, jen s vyu₧itφm performance counteru.
#include "stdafx.h"
#include "stdio.h"
#include <windows.h> // hlaviΦkov² soubor pro windows, aby Üla aplikace zkompilovat
int main(int argc, char* argv[])
{
__int64 frekvence, start, stop;
double cas;
if (!QueryPerformanceFrequency((LARGE_INTEGER*)&frekvence)) // Zjistφme frekvenci performance counteru
{
printf("Vas hardware nepodporuje Performance Counter\n");
return 0; // Hardware nepodporuje Performance Counter proto skonΦφme bez m∞°enφ
}
// Zm∞°φme poΦßteΦnφ hodnotu na performance counteru
QueryPerformanceCounter((LARGE_INTEGER*)&start);
printf("Merena funkce printf\n");
// Zm∞°φme koneΦnou hodnotu na performance counteru
QueryPerformanceCounter((LARGE_INTEGER*)&stop);
// VypoΦteme z nam∞°en²ch hodnot ub∞hl² Φas (v sekundßch)
cas = ((double)(stop-start))/(double)frekvence;
// VypφÜeme nam∞°enΘ hodnoty
printf("Performance counter na tomto pocitaci pracuje s frekvenci %d\n",frekvence);
printf("Namereny cas: %f milisekund\n",cas*1000.0);
return 0;
}
Na mΘm poΦφtaΦi jsem nam∞°il frekvenci performance counteru 1 193 180 Hz a provedenφ funkce printf trvalo 0,07 milisekund. (To je p°ibli₧n² pr∙m∞r n∞kolika m∞°enφ.)
Schvßln∞ vßm doporuΦuji vyzkouÜet si pro zajφmavost skuteΦnΘ periody volßnφ timeru v klasickΘ aplikaci pro Windows. Jß jsem to ud∞lal u MFC aplikace na bßzi dialogu a vyÜly mi tyto pr∙m∞rnΘ hodnoty.
Nastavenß hodnota intervalu timeru v milisekundßch | SkuteΦn² interval volßnφ timeru v milisekundßch |
0 | 54,6 |
10 | 54,6 |
20 | 54,6 |
30 | 54,6 |
40 | 54,6 |
50 | 54,6 |
60 | 109,5 |
70 | 109,5 |
80 | 109,5 |
90 | 109,5 |
100 | 109,5 |
110 | 109,5 |
120 | 164,5 |
160 | 164,5 |
170 | 219,6 |
220 | 219,6 |
230 | 274,5 |