..::P°esnΘ m∞°enφ Φasu::..

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