Zdravím, píšu sem, protože mě už bolí hlava s celodeního googlení a prohledávání fórka...mám problém, že chci dát do svých matematických programů měření času výpočtu....našel jsem mnoho způsobů, mnoho z nich nefungovalo a ty co fungují, tak fungují nějak pofidérně (nebo já s nimi pofidérně zacházím). Poslední věc, kterou jsem zkoušel bylo z <ctime> vypsat čas jako rozdíl, který získám odečtením dvou proměných, do kterých byla nahrána časová hodnota....(clock_t cas1 = clock(); clock_t cas2 = clock();) vysledek ovsem pro stejný program pokaždé zabral jiný čas...navíc byl v pofidérných milisekundách....takže moje otázka zní co s tím, prostě nejak to přepočítat z výkonu procesoru nebo tak něco, nevím jak to funguje ale cítím, že by to nějak mohlo takhle fungovat. Prostě je blbost, aby mě vycházel stále jiný čas....a další věc jestli by to nešlo nějak stáhnout z milisekund na mikrosekundy.....za pomoc budu vděčný, prosím žádné odkazování na googl, toho jsem si dnes užil dost, radši bych viděl něco konkrétního co je ozkoušené, že funguje.....předem děkuji
Fórum › C / C++
C++ co nejpřesnější čas
Nejjednodušší a v praxi nejpoužívanější (pokud jde jen o zjišťování délky samotného výpočtu) je ten výpočet minimálně 10000× zopakovat. Nenapsal jsi, jaký používáš OS - veškeré přesnější měření je závislé na OS. Ale i tak se dostaneš jen na milisekndy - proto to opakování. PC není ta nejlepší platforma na přesná měření času.
Nejjednodušší je použít funkci GetTickCount() http://msdn.microsoft.com/en-us/library/windows/desktop/ms724408%28v=vs.85%29.aspx - ta vrací milisekundy od spuštění systému. Přesnost je typicky 10-16 ms. Pokud však výpočet zopakuješ dostečněkrát, tak získáš celkem velkou přesnost.
#8 Franceq
Jak jsem psal výše - pro účely měření daný problém vyřeší třeba milionkrát za sebou a změřený čas potom vydělí milionem.
Přilinkování knihovny není problém - co používáš za IDE? Teď si ještě nejsem jist, ale na funkci GetTickCount pravděpodobně budeš potřebovat mít stažené WinAPI (zdarma na stránkách Microsoftu)
#1 Franceq
Na přesnější měření jsem vždycky používal WinAPI funkce:
QueryPerformanceCounter (Vrací hodnotu čítače s vysokým rozlišením)
QueryPerformanceFrequency (Vrací frekvenci čítače s jakou čítá nahoru)
Obě jsou v kernel32.lib
Ta frekvence je na PC tuším alespoň 1,18MHz, dnes často i přímo frekvence procesoru
tj. Rozlišení minimálně na mikrosekundy a lepší.
Ještě pro upřesnění dodám že rozlišení měření času a přesnost měření času
jsou dvě různé věci. S rozlišením není ani na PC problém.
S přesností je to horší, protože tvůj program neběží na počítači sám,
jsou tu stovky běžících programů, procesů, ale jenom jeden nebo pár procesorů.
Aby windows vytvořil zdání, že všechny tyhle úlohy běží současně, rychle mezi nimi
přepíná, tj. chvilku běží ta úloha, chvilku jiná. Problém je že ty nevíš kdy se to stane
a stane se to i třeba v okamžiku kdy zrovna měříš. Tvůj program je na chviličku pozastaven
(windows ti ukradne procesor :-) ) a běží jiný, za chvíli ti ho vrátí, ale o tu chvilku
kdy si ho neměl je přesnost tvého měření zprzněna a výsledná hodnota měření času zašuměna
nepravidelnými a nepředvídatelnými událostmi. I věci jako že uživatel hejbne s myší,
nebo systém zrovna přistupuje ke stránkovacímu souboru, dojde k nějaké události na portech,
přerušení od nějakého zařízení a já nevím co všechno se v systému děje.
Nedá se to předvídat. Ale s určitými omezeními lze dopady těchle věcí minimalizovat.
Můžeš v průběhu měření dočasně nastavit procesu vyšší prioritu (pokud je měření krátké, i tu nejvyšší prioritu), zvýšíš tím šanci
že ti windows procesor neukradne. Ale není to jistota. Zbylý šum se dá odfiltrovat
jak už tu psal yaqwsx tím že měření opakuješ vícekrát a zprůměruješ to (před zprůměrováním
je dobré odstranit ty největší hodnoty).
S takovými opatřeními se dá dosáhout i mikrosekundové přesnosti.
Tady máš ukázkový kód. Jak připojit knihovnu kernel32.lib nemusíš ve většině
Vývojových prostředí (IDE) řešit, bývá připojena automaticky
Ukázkový kód chodí ve Visual Studiu i DevC++
#include <windows.h>
#include <stdio.h>
// Pocet vzorku, kolikrat se ma merit
#define SAMPLES 1000
// Definice 64-bitoveho integeru (starší verze Visual Studia nemají typ long long)
#if defined(_MSC_VER)
typedef __int64 INT64;
#else
typedef long long INT64;
#endif
// Funkce QueryPerformance... pozaduji parametr typu LARGE_INTEGER,
// pro snazsi dalsi pocitani s vracenym 64bitovým integerem si definuju union
union COUNTER {
LARGE_INTEGER li;
INT64 i64;
};
void MerenaRutina()
{
printf("");
}
int main(int argc, char* argv[])
{
COUNTER freq, a, b;
INT64 empty, sum, average;
int i;
double s;
// Zjisteni frekvence citace
QueryPerformanceFrequency(&freq.li);
// Zjisti jak dlouho trva samotne volani QueryPerformanceCounter
QueryPerformanceCounter(&a.li);
QueryPerformanceCounter(&b.li);
empty = b.i64 - a.i64;
// Samotne mereni opakovane SAMPLES-krát
sum = 0;
for (i = 0; i < SAMPLES; i++) {
QueryPerformanceCounter(&a.li);
MerenaRutina();
QueryPerformanceCounter(&b.li);
sum += b.i64 - a.i64;
}
// Jaký je prumerny cas
average = sum / SAMPLES;
average -= empty;
if (average < 0) average = 0;
s = (double) average / (double) freq.i64;
printf("\nJedno volani MerenaRutina() trva prumerne: %g mikrosekund\n", s * 1000000.0);
getchar();
return 0;
}
Pardon, to opakované volání QueryPerformanceCounter v cyklu je zbytečné
(samotná režie cyklu má tady v podstatě nulovej vliv)
lepší takto:
QueryPerformanceCounter(&a.li);
for (i = 0; i < SAMPLES; i++) {
MerenaRutina();
}
QueryPerformanceCounter(&b.li);
sum = b.i64 - a.i64;
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Moderátoři diskuze