2012-06-16 16 views
16

Chcę zmierzyć środowisko wykonawcze mojego kodu C++. Wykonanie mojego kodu trwa około 12 godzin i chcę napisać ten czas pod koniec realizacji mojego kodu. Jak mogę to zrobić w moim kodzie?Mierzenie środowiska wykonawczego kodu C++?

System operacyjny: Linux

+1

W jakim systemie operacyjnym uruchomiony jest Twój kod? –

+0

Lubię profilować wiele kodów naraz. – Puppy

+1

po prostu użyj komendy 'time' po uruchomieniu dowolnego programu. – Jasen

Odpowiedz

7

kiedyś coś takiego w jednym z moich projektów:

#include <sys/time.h> 

struct timeval start, end; 
gettimeofday(&start, NULL); 
//Compute 
gettimeofday(&end, NULL); 
double elapsed = ((end.tv_sec - start.tv_sec) * 1000) 
     + (end.tv_usec/1000 - start.tv_usec/1000); 

To dla milisekund i działa zarówno w C i C++.

54

Jeśli używasz C++ 11 można użyć system_clock::now():

auto start = std::chrono::system_clock::now(); 

/* do some work */ 

auto end = std::chrono::system_clock::now(); 
auto elapsed = end - start; 
std::cout << elapsed.count() << '\n'; 

Można także określić szczegółowość użyć do reprezentowania czas trwania:

// this constructs a duration object using milliseconds 
auto elapsed = 
    std::chrono::duration_cast<std::chrono::milliseconds>(end - start); 

// this constructs a duration object using seconds 
auto elapsed = 
    std::chrono::duration_cast<std::chrono::seconds>(end - start); 

Jeśli nie można używać C + +11, następnie spójrz na chrono z Boost.

Najlepszą rzeczą w używaniu takich standardowych bibliotek jest to, że ich przenośność jest naprawdę wysoka (np. Oba działają w systemie Linux i Windows). Nie musisz więc zbytnio się martwić, jeśli później zdecydujesz się na przeniesienie aplikacji.

Biblioteki te są również zgodne z nowoczesnym wyglądem C++, w przeciwieństwie do podejść w stylu C-podobnym.

EDYCJA: Powyższy przykład może służyć do pomiaru wall-clock time. Nie jest to jednak jedyny sposób na zmierzenie czasu wykonania programu. Po pierwsze, możemy odróżnieniu od użytkownika i systemu czasu:

  • czas użytkownika: Czas spędzony przez program uruchomiony w user space.
  • Czas systemowy: Czas spędzony przez program działający w przestrzeni systemowej (lub jądra). Program wprowadza przestrzeń jądra na przykład podczas wykonywania system call.

W zależności od celów może być konieczne lub nie uwzględnienie czasu systemowego w ramach czasu realizacji programu. Na przykład, jeśli celem jest po prostu zmierzenie optymalizacji kompilatora kodu użytkownika, prawdopodobnie lepiej jest pominąć czas systemowy. Z drugiej strony, jeśli użytkownik chce ustalić, czy wywołania systemowe są znaczącym obciążeniem, to konieczne jest również zmierzenie czasu systemowego.

Ponadto, ponieważ większość nowoczesnych systemów to time-shared, różne programy mogą konkurować o kilka zasobów obliczeniowych (np. Procesor). W takim przypadku, inna można rozróżnić:

  • Wall-clock time: Stosując upływ czasu wykonanie programu jest mierzona w taki sam sposób, jak to zostało za pomocą zewnętrznego (ściana) zegara. Takie podejście nie uwzględnia interakcji pomiędzy programami.
  • CPU time: W tym przypadku liczymy tylko czas, w którym program faktycznie działa na procesorze.Jeśli program (P1) jest współpisany z innym (P2) i chcemy uzyskać czas procesora dla P1, to podejście nie obejmuje czasu, gdy P2 jest uruchomione, a P1 czeka na procesor (w przeciwieństwie do podejście do zegara ściennego).

Do pomiaru czasu procesora, doładowania zawiera set of extra clocks:

  • process_real_cpu_clock, przechwytuje ścienny zegar czasu procesora spędzony w obecnym procesie.
  • process_user_cpu_clock, przechwytuje czas procesora użytkownika spędzony przez bieżący proces.
  • process_system_cpu_clock, przechwytuje czas procesora systemowego wydany przez bieżący proces. Klasa podobna do krotki process_cpu_clock, która rejestruje razem rzeczywisty czas procesora użytkownika i procesora systemowego.
  • Stały zegar w wątku, który daje czas spędzony przez bieżący wątek (jeśli jest obsługiwany przez platformę).

Niestety, C++ 11 nie ma takich zegarów. Ale Boost jest szeroko używaną biblioteką i prawdopodobnie te dodatkowe zegary zostaną w pewnym momencie włączone do C++ 1x. Tak więc, jeśli użyjesz Boost, będziesz gotowy, gdy nowy standard C++ je doda.

Na koniec, jeśli chcesz zmierzyć czas, jaki program musi wykonać w wierszu poleceń (w przeciwieństwie do dodania kodu do twojego programu), możesz rzucić okiem na komendę time, tak jak sugeruje to @ BЈовић. Takie podejście jednak nie pozwoli ci zmierzyć poszczególnych części twojego programu (np. Czasu potrzebnego do wykonania funkcji).

+0

moje pytanie brzmi: jak o C++/C++ 11 różnice i boost-biblioteki? – gaussblurinc

+1

@loldop Wierzę, że implementacja C++ 11 jest podzbiorem biblioteki chronografu Boost. Powinni więc mieć bardzo podobne API (jeśli nie to samo). Zaletą korzystania z C++ 11 jest to, że nie musisz używać Boost (jeśli chrono jest jedyną biblioteką, którą chcesz uzyskać z Boost). – betabandido

10

Możesz użyć time, aby uruchomić program. Kiedy się kończy, drukuje ładne statystyki czasu dotyczące przebiegu programu. Łatwo skonfigurować to, co chcesz wydrukować. Domyślnie drukuje czasy użytkowników i procesorów potrzebne do uruchomienia programu.

EDIT: Weź pod uwagę, że każde działanie z kodem nie jest prawidłowe, ponieważ aplikacja będzie zablokowane przez inne programy, a tym samym daje błędne wartości *.

* błędnymi wartościami, miałem na myśli to jest łatwo dostać czasu zajęło, aby uruchomić program, ale że czas zmienia się w zależności od obciążenia CPU w trakcie realizacji programu. Aby uzyskać względnie stabilny pomiar czasu, który nie zależy od obciążenia procesora, można uruchomić aplikację przy użyciu time i użyć CPU jako wyniku pomiaru.

+1

Myślę, że blokowanie jest również częścią czasu, w którym program ma działać, nie? –

+1

@EitanT Nie, ponieważ obciążenie procesora (CPU) się zmienia. Obciążenie prądem nie musi być takie samo jak obciążenie w ciągu 1 godziny lub jutro. –

+0

Teraz widzę co masz na myśli. –

16

Użyj std::chrono::steady_clock, a nie std::chrono::system_clock do pomiaru czasu pracy w C++ 11. Powodem jest (cytując system_clock „s dokumentacji):

na większości systemów, czas systemowy można ustawić w dowolnym momencie

podczas steady_clock jest monotoniczny i lepiej nadaje się do przedziałów pomiarowych:

Class std :: chrono :: steady_clock reprezentuje zegar monotoniczny. Czas ten nie może się zmniejszyć w czasie, gdy czas fizyczny porusza się do przodu. Ten zegar nie jest powiązany z czasem zegara ściennego i najlepiej nadaje się do interwałów pomiarowych .

Oto przykład:

auto start = std::chrono::steady_clock::now(); 
// do something 
auto finish = std::chrono::steady_clock::now(); 
double elapsed_seconds = std::chrono::duration_cast< 
    std::chrono::duration<double> >(finish - start).count(); 

Mała praktyczna wskazówka: jeśli pomiar czasu pracy i chcą zgłosić sekund std::chrono::duration_cast<std::chrono::seconds> rzadko jest to, czego potrzebujesz, ponieważ daje cały liczbę sekund. Aby uzyskać czas w sekundach jako double użyj powyższego przykładu.

+0

Nie otrzymałem praktycznej wskazówki. Czy nie jest 'std :: chrono :: duration_cast ' sposobem na uzyskanie różnicy między dwoma punktami czasowymi jako całkowitymi sekundami? – Isaac

+0

@Isaac Co mam na myśli to, że 'std :: chrono :: duration_cast ' zwróci 0, jeśli różnica jest mniejsza niż sekunda. Jeśli chcesz mieć czas trwania jako liczbę zmiennoprzecinkową, użyj 'double' zamiast' seconds'. – vitaut

0

Można również spróbować niektórych klas timer, który automatycznie start i stop, i zbierać statystyki dotyczące średniej, maksymalnej i minimalnej czasu spędzonego w każdym bloku kodu, jak i liczby połączeń. Te klasy cxx-rtimer są dostępne pod numerem GitHub i oferują wsparcie dla używania std :: chrono, clock_gettime() lub boost :: posix_time jako back-endowego źródła zegara.

Z tych zegarów, można zrobić coś takiego:

void timeCriticalFunction() { 
    static rtimers::cxx11::DefaultTimer timer("expensive"); 
    auto scopedStartStop = timer.scopedStart(); 
    // Do something costly... 
} 

o taktowaniu statystyk piśmie std :: cerr po zakończeniu programu.

Powiązane problemy