C++ co nejpřesnější čas – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

C++ co nejpřesnější čas – C / C++ – Fórum – Programujte.comC++ co nejpřesnější čas – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
Franceq+1
Stálý člen
27. 10. 2011   #1
-
0
-

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

Nahlásit jako SPAM
IP: 31.133.8.–
yaqwsx+9
Posthunter
27. 10. 2011   #2
-
0
-

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.

Nahlásit jako SPAM
IP: 85.160.96.–
Life is too short to remove USB mass storage safely...
Správný drsňák udělá z konzole cokoliv
Franceq+1
Stálý člen
27. 10. 2011   #3
-
0
-

používám windows

Nahlásit jako SPAM
IP: 31.133.8.–
yaqwsx+9
Posthunter
27. 10. 2011   #4
-
0
-
Nahlásit jako SPAM
IP: 85.160.96.–
Life is too short to remove USB mass storage safely...
Správný drsňák udělá z konzole cokoliv
Franceq+1
Stálý člen
27. 10. 2011   #5
-
0
-

vyžaduje to Kernel32.lib  a ja neumi připojovat knihovny....:_((

Nahlásit jako SPAM
IP: 31.133.8.–
Franceq+1
Stálý člen
27. 10. 2011   #6
-
0
-

jak funguje CLOCKS_PER_SEC ....nedá se to přes to nějak ošéfovat?

Nahlásit jako SPAM
IP: 31.133.8.–
m->29+6
Super člen
27. 10. 2011   #7
-
0
-

Ak použiješ 

clock() / CLOCKS_PER_SEC

tak ti to vráti sekundy. Na milisekundy sa dostaneš ťažko. A ak aj, tak to asi moc presné aj tak nebude.

Nahlásit jako SPAM
IP: 83.240.51.–
Franceq+1
Stálý člen
27. 10. 2011   #8
-
0
-

hmm škoda....nechápu jak to dělaj ty blázni na projecteuler co časy svých projektů uvádějí v mikrosekundách....

Nahlásit jako SPAM
IP: 31.133.8.–
yaqwsx+9
Posthunter
27. 10. 2011   #9
-
0
-

#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)

Nahlásit jako SPAM
IP: 85.160.96.–
Life is too short to remove USB mass storage safely...
Správný drsňák udělá z konzole cokoliv
Franceq+1
Stálý člen
28. 10. 2011   #10
-
0
-

co je to IDE?

Nahlásit jako SPAM
IP: 31.133.8.–
Pudni tvor+2
Stálý člen
29. 10. 2011   #11
-
0
-

#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ší.

Nahlásit jako SPAM
IP: 90.180.213.–
Pudni tvor+2
Stálý člen
29. 10. 2011   #12
-
0
-

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.

Nahlásit jako SPAM
IP: 90.180.213.–
Pudni tvor+2
Stálý člen
29. 10. 2011   #13
-
+1
-
Zajímavé

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;
}
Nahlásit jako SPAM
IP: 90.180.213.–
Pudni tvor+2
Stálý člen
29. 10. 2011   #14
-
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;
Nahlásit jako SPAM
IP: 90.180.213.–
Franceq+1
Stálý člen
29. 10. 2011   #15
-
0
-

děkuji moc, tohle jsem přesně potřeboval, vyvoslit to pro vosla....díky moc, moc mi to pomohlo

Nahlásit jako SPAM
IP: 31.133.8.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 32 hostů

Podobná vlákna

Čas — založil šampík

čas v c++ — založil programator453

Čas — založil Kenvelo

Čas v title — založil Frozen

Ubehnuty cas — založil dalaman

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý