Jaka jest różnica między std::system_clock
i std::steady_clock
? (Przykładowy przypadek ilustrujący różne wyniki / zachowania byłby świetny).
Jeśli moim celem jest precyzyjny pomiar czasu wykonywania funkcji (np. Benchmarku), jaki byłby najlepszy wybór pomiędzy std::system_clock
, std::steady_clock
a std::high_resolution_clock
?
system_clock
w systemie Windows nie jest stabilny. W systemie Windows czas systemowy może zostać zmieniony na dowolną wartość przez dowolnego wystarczająco uprzywilejowanego użytkownika. Ponadto usługa synchronizacji czasu może w razie potrzeby cofnąć czas systemowy. Spodziewam się, że większość innych platform ma podobne funkcje, które umożliwiają dostosowanie czasu systemowego.Odpowiedzi:
Od N3376:
20.11.7.1 [time.clock.system] / 1:
20.11.7.2 [time.clock.steady] / 1:
20.11.7.3 [time.clock.hires] / 1:
Na przykład na zegar systemowy może mieć wpływ coś w rodzaju czasu letniego, w którym to momencie rzeczywisty czas podany w pewnym momencie w przyszłości może w rzeczywistości należeć do przeszłości. (Np. W USA jesienią czas cofa się o godzinę, więc ta sama godzina jest przeżywana „dwa razy”). Jednak
steady_clock
takie rzeczy nie mają na to wpływu.Innym sposobem myślenia o „stabilnym” w tym przypadku są wymagania określone w tabeli 20.11.3 [time.clock.req] / 2:
To wszystko, co standard ma na temat ich różnic.
Jeśli chcesz przeprowadzić test porównawczy, prawdopodobnie najlepszym rozwiązaniem będzie
std::high_resolution_clock
, ponieważ jest prawdopodobne, że Twoja platforma używa zegara o wysokiej rozdzielczości (np. WQueryPerformanceCounter
systemie Windows) dla tego zegara. Jeśli jednak przeprowadzasz testy porównawcze, naprawdę powinieneś rozważyć użycie timerów specyficznych dla platformy do swojego testu porównawczego, ponieważ różne platformy radzą sobie z tym inaczej. Na przykład niektóre platformy mogą zapewniać pewne sposoby określania rzeczywistej liczby taktów zegara wymaganych przez program (niezależnie od innych procesów uruchomionych na tym samym procesorze). Jeszcze lepiej, zdobądź prawdziwy profiler i użyj go.źródło
steady_clock
isystem_clock
tutaj.system_clock
czasu UTC.Billy udzielił świetnej odpowiedzi opartej na standardzie ISO C ++, z którym w pełni się zgadzam. Jest jednak druga strona tej historii - prawdziwe życie. Wygląda na to, że w tej chwili tak naprawdę nie ma różnicy między tymi zegarami w implementacji popularnych kompilatorów:
gcc 4.8:
Visual Studio 2012:
W przypadku gcc możesz sprawdzić, czy masz do czynienia z zegarem stałym, po prostu sprawdzając
is_steady
i odpowiednio się zachowując. Jednak VS2012 wydaje się tutaj trochę oszukiwać :-)Jeśli potrzebujesz zegara o wysokiej precyzji, polecam na razie napisać własny zegar zgodny z oficjalnym interfejsem zegara C ++ 11 i poczekać, aż implementacje nadrobią zaległości. Będzie to znacznie lepsze podejście niż używanie interfejsu API specyficznego dla systemu operacyjnego bezpośrednio w kodzie. W systemie Windows możesz to zrobić w ten sposób:
W przypadku Linuksa jest to jeszcze łatwiejsze. Po prostu przeczytaj stronę podręcznika man
clock_gettime
i zmodyfikuj powyższy kod.źródło
Wdrożenie GCC 5.3.0
C ++ stdlib znajduje się w źródle GCC:
high_resolution_clock
jest aliasem dlasystem_clock
system_clock
przekierowuje do pierwszej z dostępnych opcji:clock_gettime(CLOCK_REALTIME, ...)
gettimeofday
time
steady_clock
przekierowuje do pierwszej z dostępnych opcji:clock_gettime(CLOCK_MONOTONIC, ...)
system_clock
Następnie
CLOCK_REALTIME
vsCLOCK_MONOTONIC
jest wyjaśnione na: Różnica między CLOCK_REALTIME i CLOCK_MONOTONIC?źródło
Być może najbardziej znaczącą różnicą jest fakt, że punktem wyjścia
std::chrono:system_clock
jest 1.1.1970, tzw. Epoka UNIX. Z drugiej strony,std::chrono::steady_clock
zwykle dla czasu uruchamiania komputera i najlepiej nadaje się do mierzenia odstępów czasu.źródło