Avatar billede zer0c00l Juniormester
16. maj 2006 - 11:38 Der er 18 kommentarer og
2 løsninger

Tidstagning i C++

Hej eksperter..

Jeg har en funktion i C++, der indlæser nogle værdier fra com-porten. Det vil være forskelligt, hvor mange værdier, der indlæses, og jeg skal bruge den tid, det tager, at få indlæst værdierne.

Er der en funktion, jeg kan sætte i gang, når første værdi modtages og stoppe, når den sidste værdi er modtaget, og så beregne, hvor lang tid dette har taget?

På forhånd tak ;)
Avatar billede arne_v Ekspert
16. maj 2006 - 13:08 #1
time_t t1 = time(NULL);
...
time_t t2 = time(NULL);

og så brug difftime(t2, t1)
Avatar billede arne_v Ekspert
16. maj 2006 - 13:08 #2
#include <time.h>

eller

#include <ctime>
Avatar billede bertelbrander Novice
16. maj 2006 - 20:07 #3
Man kan måske opnå større nøjagtighed med clock:

#include <time.h>
#include <iostream>

int main()
{
  clock_t Start = clock();
  std::cout << "Hit Enter at any time" << std::endl;
  std::cin.get();
  clock_t End = clock();

  std::cout << "You waited: " << (End - Start)/CLOCKS_PER_SEC << " Seconds" << std::endl;
}

Er det ikke godt nok, og bruger du windows kan du bruge QueryPerformanceCounter sammen med QueryPerformanceFrequency
Avatar billede arne_v Ekspert
16. maj 2006 - 20:15 #4
clock og time maaler noget forskelligt

clock maaler CPU time

time maaler wall time

for en CPU intensiv operation er de typisk ret ens

men for at laese fra en COM port vil jeg forvente at de er meget forskellige
Avatar billede bertelbrander Novice
16. maj 2006 - 23:03 #5
Havde glemt den "feature" ved clock :-(

En løsning med QueryPerformanceCounter:

#include <iostream>
#include <windows.h>

int main(void)
{
  LARGE_INTEGER Freq;
  LARGE_INTEGER Start;
  QueryPerformanceFrequency(&Freq);
  QueryPerformanceCounter(&Start);
  std::cout << "Hit Enter at any time" << std::endl;
  std::cin.get();
  LARGE_INTEGER End;
  QueryPerformanceCounter(&End);

  std::cout << "You waited: " << double(End.QuadPart - Start.QuadPart)/Freq.QuadPart << " Seconds" << std::endl;
}
Avatar billede zer0c00l Juniormester
17. maj 2006 - 10:56 #6
Problemet er lidt, at den skal tælle mere nøjagtigt en sekunder.. Den skal faktisk ned og tælle i millisekunder! Vi har et input af der, der bliver gemt i et array. Timeren skal starte, når det første tal skrives til arrayet og stoppe, når det sidste tal er lagret. Håber, det er til at forstå :)
Avatar billede arne_v Ekspert
17. maj 2006 - 13:06 #7
så skal du over i noget platform/compiler specifikt

Unix/Linux : gettimeofday

Windows : GetLocalTime (eller Bertels QueryPerformance functions)
Avatar billede bertelbrander Novice
17. maj 2006 - 19:50 #8
QueryPerformanceCounter kan let måle i milisekunder, på min PC er frekvensen 3579545, dvs ca 280 nano sekunder/tick.

Du kan bruge:

  std::cout << "You waited: " << double(End.QuadPart - Start.QuadPart)*1000/Freq.QuadPart << " Millisekunder" << std::endl;
Avatar billede zer0c00l Juniormester
18. maj 2006 - 08:40 #9
bertelbrander >> Det bliver jo ikke mere præcist af, at du ganger tllet med 1000.. Så vil du bare få værdierne 1000, 2000, 3000, 4000 osv. Du vil aldrig kunne få den til at vise 2384 for eksempel.
Avatar billede bertelbrander Novice
18. maj 2006 - 19:17 #10
Nej, den bliver ikke mere nøjagtig af at man ganger med 1000, resultatet bliver blot vist i ms i stedet for sekunder.

Men den har en opløsning der er meget bedre end millisekunder, så den kan godt måle 2384 ms.

Den skriver ikke bare 1000, 2000, 3000, 4000 osv. Det ville den gøre hvis Freq.QuadPart var 1, men den er mange gange større, som jeg skrev er den 3579545 på min PC.

Den skriver resultatet som en double.

Prøv en gang at køre koden og se hvad den skriver.
Avatar billede zer0c00l Juniormester
22. maj 2006 - 14:03 #11
Undskyld ventetiden! Kigger på det 1st thing i morgen :D
Avatar billede karas Nybegynder
24. maj 2006 - 16:52 #12
Hvis jeg var dig så ville jeg bruge CPUens Time Stamp Counter (TSC). Du får ikke tiden i sekunder, men i clock cycler. Om du kan bruge det i stedet ved jeg ikke, men hvis ikke kan du altid omregne det til tid senere.

For at læse TSC skal du ned i assembly code:

unsigned __int64 tsc;
__asm {
rdtsc        ; Read Time Stamp Counter (value stored in EDX:EAX)
mov DWORD PTR[tsc], eax
mov DWORD PTR[tsc+4], edx
}

Denne metode er uafhængig af styresystemet og du kan ikke komme i nærheden af samme præcision med nogle af de andre forslag.

Note: Du skal være sikker på at CPUen understøtter 'rdtsc' instructionen (det gør alle AMD CPUer i Athlon familien og alle Intel CPUer fra Pentium af) samt at fx. styresystemet ikke har lavet restriktioner på brugen af instructionen (som default gør windows ikke).
Avatar billede karas Nybegynder
24. maj 2006 - 17:04 #13
Forresten, jeg glemte lige at sige noget.

rdtsc instructionen bliver ikke automatisk serialized. Dvs. at hvis du skal være sikker på at rdtsc ikke "overhaler" andre instructioner i CPUens pipeline, så skal du først eksekvere en serialiserende instruction som fx 'cpuid':
__asm {
cpuid
rdtsc        ; Read Time Stamp Counter (value stored in EDX:EAX)
mov DWORD PTR[tsc], eax
mov DWORD PTR[tsc+4], edx
}

Jeg tvivler på at du har brug for at regne så præcist, men man ved jo aldrig...
Avatar billede arne_v Ekspert
24. maj 2006 - 18:30 #14
hvordan reagerer TSC naar en Pentium M skruer ned for frekvensen for at spare stroem ?
Avatar billede karas Nybegynder
24. maj 2006 - 18:39 #15
Den giver det samme resultat. Det er jo clock >frekvensen< der justeres. Antallet af clocks ændres ikke.

Men hvis man selv finder frekvensen og skal omregne clocks til tid, så skal man selvfølgelig tage højde for ændringer i frekvensen - hvis det sker, det kommer jo an på systemet.
Avatar billede arne_v Ekspert
18. juni 2006 - 21:01 #16
Tid at få afsluttet her ?
Avatar billede zer0c00l Juniormester
19. juni 2006 - 12:05 #17
problemet blev løst lidt alternativt, men smid nogle svar, så kan i dele point
Avatar billede arne_v Ekspert
19. juni 2006 - 12:34 #18
ok
Avatar billede karas Nybegynder
19. juni 2006 - 19:14 #19
og hvordan løste du så problemet?
Avatar billede zer0c00l Juniormester
19. juni 2006 - 23:31 #20
Jeg skal faktisk ikke kunne sige, hvad det endte med.. Det var til et skole-projekt, og det var ikke lige mig, der stod for C++-delen.. Jeg forsøgte bare at hjælpe dem :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester