De la traducător:
Majoritatea cunoștințelor mele de a măsura timpul în diferite tipuri de repere în C ++ utilizează crono sau, în cazuri mai puțin neglijate, ctime. Dar pentru benchmarking este mult mai util să măsurați timpul procesorului. Recent am descoperit un articol despre măsurarea pe mai multe platforme a timpului CPU și am decis să îl împărtășim aici, eventual mărind ușor calitatea referințelor locale.
Cum se obține timpul procesorului
Timpul procesorului crește atunci când procesul este în execuție și consumă ciclurile procesorului. În timpul operațiilor de I / O, blocarea firului și alte operații care suspendă procesorul, timpul procesorului nu crește până când procesul din nou începe să utilizeze CPU-ul.
Instrumente diferite, cum ar fi PS în POSIX, Monitor de activitate în OSX și Task Manager pe Windows, arată timpul procesorului folosit de procese, dar este adesea util să-l urmăriți chiar de la procesul în sine. Acest lucru este util în special atunci când algoritmii de benchmarking sau o mică parte a unui program complex. În ciuda faptului că toate sistemele de operare oferă API pentru obținerea timpului procesorului, fiecare dintre ele are propriile subtilități.
Funcția getCPUTime (). Codul de mai jos funcționează pe majoritatea sistemelor de operare (copiați codul sau descărcați fișierul getCPUTime.c). Atunci când este necesar, link-ul către librt. pentru a obține cronometre POSIX (de exemplu, AIX, BSD, Cygwin, HP-UX, Linux și Solaris, dar nu OSX). În caz contrar, bibliotecile standard sunt suficiente.
Apoi, vom discuta în detaliu toate funcțiile, subtilitățile și motivele pentru care există #devete în cod.
utilizarea
Pentru a măsura timpul procesorului algoritmului, apelați getCPUTime () înainte și după rularea algoritmului și extrageți diferența. Nu este necesar să presupunem că valoarea returnată de un apel de o singură funcție are un sens.
discuție
Fiecare sistem de operare oferă una sau mai multe modalități de a obține timp CPU. Cu toate acestea, unele metode sunt mai exacte decât altele.
Fiecare dintre aceste metode este detaliată mai jos.
GetProcessTimes ()
Pe Windows și Cygwin (mediu și interfață linie de comandă UNIX pentru Windows), funcția GetProcessTimes () umple timpul structurii procesorului a datei atașării utilizate de proces, și funcția FileTimeToSystemTime () convertește o structură de SYSTEMTIME structură a datei atașării. conținând o valoare de timp utilă.
Availability GetProcessTimes (): Cygwin, Windows XP și mai târziu.
Primirea timpului CPU:
clock_gettme ()
Pe cele mai multe sisteme de operare-POSIX, clock_gettime () (a se vedea manualele pentru AIX. BSD. HP-UX. Linux și Solaris) oferă valoarea cea mai exactă a timpului CPU. Primul argument al funcției selectează "id clock", iar al doilea este structura timepec. Umplut cu timpul procesorului utilizat în secunde și nanosecunde. Pentru majoritatea sistemelor de operare, programul trebuie să fie legat de librt.
Cu toate acestea, există mai multe subtilități care fac dificilă utilizarea acestei funcții în codul cross-platform:
- Funcția este o parte opțională a standardului POSIX și este disponibilă numai dacă este definită funcția _POSIX_TIMERS
Valoarea este mai mare decât 0. În prezent, AIX, BSD, HP-UX, Linux și Solaris acceptă această funcție, însă OSX nu o acceptă. - Structura lui timespec. Funcția clock_gettime () poate stoca timpul în nanosecunde, dar acuratețea ceasului diferă în diferite sisteme de operare și pe sisteme diferite. Funcția clock_getres () returnează precizia ceasului dacă aveți nevoie de ea. Această funcție, din nou, este o parte opțională a standardului POSIX, care este disponibilă numai dacă _POSIX_TIMERS este mai mare decât zero. În prezent, AIX, BSD, HP-UX, Linux și Solaris oferă această caracteristică, dar pe Solaris nu funcționează.
- standardul POSIX definește numele mai multor valori standard ale "ceasului", inclusiv CLOCK_PROCESS_CPUTIME_ID. pentru a obține timpul procesorului procesului. Cu toate acestea, astăzi BSD și HP-UX nu au acest id și în schimb își definesc propriul id CLOCK_VIRTUAL pentru timpul procesorului. Pentru a confunda orice altceva, Solaris definește ambele, dar folosește CLOCK_VIRTUAL pentru timpul CPU al threadului. nu un proces.
Ce id de utilizat
- În loc să utilizați una dintre constantele declarate mai sus, clock_getcpuclockid () returnează un cronometru pentru procesul selectat. Utilizarea procesului 0 vă permite să obțineți timpul CPU al procesului curent. Cu toate acestea, acest lucru este o altă parte opțională a standardului POSIX și este disponibil numai în cazul în care _POSIX_CPUTIME mai mare decât 0. Până în prezent, numai AIX și Linux oferă această funcție, dar linuksovskie includ fișier nu definesc _POSIX_CPUTIME și returnează nesigure și incompatibile cu rezultatele POSIX.
- Funcția clock_gettime () poate fi implementată utilizând registrul de timp al procesorului. Pe sistemele multiprocesor, procesoarele individuale pot avea o percepție de timp oarecum diferită, din cauza căreia funcția poate reveni la valori incorecte dacă procesul a fost transferat de la procesor la procesor. Pe Linux și numai pe Linux, acest lucru poate fi detectat dacă clock_getcpuclockid () returnează o eroare non-POSIX și setează errno la ENOENT. Cu toate acestea, după cum sa menționat mai sus, pe Linux clock_getcpuclockid () nu este fiabilă.
În practică, datorită acestor subtilități, folosirea clock_gettime () necesită o mulțime de verificări cu #ifdef și abilitatea de a trece la o altă funcție dacă nu funcționează.
Disponibilitatea clock_gettime (): AIX, BSD, Cygwin, HP-UX, Linux și Solaris. Dar id-ul ceasului pe BSD și HP-UX este non-standard.
Disponibilitatea clock_getres (): AIX, BSD, Cygwin, HP-UX și Linux, dar Solaris nu funcționează.
Disponibilitatea lui clock_getcpuclockid (): AIX și Cygwin, nu este fiabilă pe Linux.
Primirea timpului CPU:
getrusage ()
La toate sistemele de operare asemănătoare UNIX, getrusage () este cea mai fiabilă metodă de a obține timpul procesorului folosit de procesul curent. Funcția umple structura rusage cu timpul în secunde și microsecunde. Câmpul ru_utime conține timpul petrecut în modul utilizator și câmpul ru_stime este în modul sistem în numele procesului.
Notă: Unele sisteme de operare, înainte de distribuirea largă a suportului pe 64 de biți, au definit funcția getrusage (). care returnează o valoare pe 32 de biți și funcția getrusage64 (). care returnează o valoare pe 64 de biți. Astăzi, getrusage () returnează o valoare pe 64 de biți și getrusage64 () este depreciată.
Disponibilitatea getrusage (): AIX, BSD, Cygwin, HP-UX, Linux, OSX și Solaris.
Primirea timpului CPU:
În toate sistemele de operare asemănătoare cu sistemele UNIX, timpii de funcții depășiți () umple structura tms cu timpul procesorului în căpușe, iar funcția sysconf () returnează numărul de căpușe pe secundă. Câmpul tms_utime conține timpul petrecut în modul utilizator, iar câmpul tms_stime este în modul sistem în numele procesului.
Avertisment: Argumentul mai vechi pentru funcția sysconf () CLK_TCK este depreciat și este posibil să nu fie acceptat în unele sisteme de operare. Dacă este disponibil, sysconf () nu funcționează de obicei atunci când îl utilizați. În schimb, utilizați _SC_CLK_TCK.
Timp de disponibilitate (): AIX, BSD, Cygwin, HP-UX, Linux, OSX și Solaris.
Primirea timpului CPU:
În toate OS-urile asemănătoare UNIX, funcția foarte veche clock () returnează timpul procesorului în căpușe, iar macro-ul CLOCKS_PER_SEC numărul de căpușe pe secundă.
Notă: timpul procesorului returnat include timpul petrecut în modul de utilizare și în modul de sistem, în numele procesului.
Notă: Deși inițial CLOCKS_PER_SEC trebuie să returneze un dependent de procesor valoric, standardele C standard ISO C89 și C99, Single UNIX Specification și POSIX necesită ca CLOCKS_PER_SEC 1.000.000 are o valoare fixă, care limitează acuratețea funcției microsecunde. Cele mai multe sisteme de operare îndeplinesc aceste standarde, însă versiunile FreeBSD, Cygwin și cele mai vechi ale OSX utilizează valori non-standard.
Notă: La AIX și Solaris, funcția clock () include timpul procesorului procesului AND actual și orice proces completat de copil pentru care părintele a efectuat una dintre funcțiile wait (). sistem () sau pclose ().
Atenție: În Windows, funcția ceas () este acceptată, dar nu returnează timpul procesorului, ci timpul real.
Ceas de disponibilitate (): AIX, BSD, Cygwin, HP-UX, Linux, OSX și Solaris.
Primirea timpului CPU:
Alte abordări
Există și alte modalități specifice OS-ului pentru a obține timp CPU. Pe Linux, Solaris și unele BSD, puteți parse / proc / [pid] / stat. pentru a obține statisticile procesului. Pe OSX, funcția API privată proc_pidtaskinfo () din libproc returnează informații despre proces. Există, de asemenea, biblioteci deschise, cum ar fi libproc, procps și Sigar.
Pe UNIX, există mai multe utilitare care vă permit să afișați timpul CPU al procesului, inclusiv ps. top. mpstat și altele. De asemenea, puteți utiliza utilitarul de timp. Pentru a afișa timpul petrecut în echipă.
Pe Windows, puteți utiliza Task Manager. pentru a monitoriza utilizarea procesorului.
Pe OSX, puteți utiliza Monitorul de activitate. pentru a monitoriza utilizarea procesorului. Utilitarul pentru Instrument Profiling furnizat cu Xcode poate monitoriza utilizarea procesorului, precum și multe alte lucruri.
- getCPUTime.c implementează funcția descrisă mai sus în C. Compilați-o cu orice compilator C și link-ul cu librt. pe sistemele în care este disponibil. Codul este licențiat sub licența Creative Commons Attribution 3.0 Unported.
Uite, de asemenea
Articole similare pe NadeauSoftware.com
- C / C ++ sfat: Cum se măsoară în timp real scurs pentru analiza comparativă explică modul de a obține în timp real pentru a măsura timpul scurs pentru o bucată de cod, inclusiv timpul petrecut pe I / O sau intrare de utilizator.
- Sfat pentru C / C ++: Cum se utilizează macrocomenzile predefinite de compilator pentru a detecta sistemul de operare explică modul de utilizare a macrocomenzilor #ifdef pentru codul specific sistemului. Unele dintre aceste metode sunt utilizate în acest articol pentru a determina variantele Windows, OSX și UNIX.
Articole pe Internet
- Timpul procesorului pe wikipedia explică ce este timpul procesorului.
- Analiza timpului CPU pe GNU.org explică modul de utilizare a funcției ceasului antic ().
- Determinarea utilizării CPU a procesului curent (C ++ și C #) oferă cod și explicații pentru obținerea timpului procesorului și a altor statistici pe Windows.
- Opțiunile Posix pe Kernel.org explică caracteristicile opționale și constantele POSIX, inclusiv _POSIX_TIMERS și _POSIX_CPUTIME.