Qual é a diferença entre std::system_clock
e std::steady_clock
? (Um exemplo de caso que ilustre resultados / comportamentos diferentes seria ótimo).
Se meu objetivo é medir com precisão o tempo de execução de funções (como um benchmark), qual seria a melhor escolha entre std::system_clock
, std::steady_clock
e std::high_resolution_clock
?
system_clock
Windows não está estável. No Windows, a hora do sistema pode ser alterada para qualquer valor arbitrário por qualquer usuário com privilégios suficientes. Além disso, o serviço de sincronização de tempo pode ajustar a hora do sistema para trás, se necessário. Espero que a maioria das outras plataformas tenha recursos semelhantes que permitem o ajuste da hora do sistema.Respostas:
De 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:
Por exemplo, o relógio amplo do sistema pode ser afetado por algo como o horário de verão, ponto no qual a hora real listada em algum momento no futuro pode realmente ser uma hora no passado. (Por exemplo, nos EUA, no outono o tempo retrocede uma hora, então a mesma hora é experimentada "duas vezes") No entanto,
steady_clock
não é permitido ser afetado por tais coisas.Outra maneira de pensar sobre "estável" neste caso está nos requisitos definidos na tabela de 20.11.3 [time.clock.req] / 2:
Isso é tudo que o padrão tem sobre suas diferenças.
Se você quiser fazer benchmarking, sua melhor aposta provavelmente será
std::high_resolution_clock
, porque é provável que sua plataforma use um cronômetro de alta resolução (por exemplo,QueryPerformanceCounter
no Windows) para este relógio. No entanto, se estiver fazendo um benchmarking, você realmente deve considerar o uso de timers específicos da plataforma para seu benchmark, porque plataformas diferentes lidam com isso de maneira diferente. Por exemplo, algumas plataformas podem fornecer alguns meios de determinar o número real de tiques do relógio que o programa requer (independente de outros processos em execução na mesma CPU). Melhor ainda, coloque as mãos em um criador de perfis de verdade e use-o.fonte
steady_clock
esystem_clock
aqui.system_clock
seja UTC.Billy deu uma ótima resposta com base no padrão ISO C ++ com o qual concordo totalmente. No entanto, há outro lado da história - a vida real. Parece que agora não há realmente nenhuma diferença entre esses relógios na implementação de compiladores populares:
gcc 4.8:
Visual Studio 2012:
No caso do gcc você pode verificar se você lida com um relógio estável simplesmente verificando
is_steady
e se comportando de acordo. No entanto, o VS2012 parece trapacear um pouco aqui :-)Se você precisa de um relógio de alta precisão, eu recomendo agora escrever seu próprio relógio em conformidade com a interface de relógio oficial do C ++ 11 e esperar que as implementações se atualizem. Será uma abordagem muito melhor do que usar a API específica do sistema operacional diretamente em seu código. Para Windows, você pode fazer assim:
Para o Linux é ainda mais fácil. Basta ler a página do manual
clock_gettime
e modificar o código acima.fonte
Implementação do GCC 5.3.0
C ++ stdlib está dentro da fonte GCC:
high_resolution_clock
é um apelido parasystem_clock
system_clock
encaminha para o primeiro dos seguintes que está disponível:clock_gettime(CLOCK_REALTIME, ...)
gettimeofday
time
steady_clock
encaminha para o primeiro dos seguintes que está disponível:clock_gettime(CLOCK_MONOTONIC, ...)
system_clock
Então
CLOCK_REALTIME
vsCLOCK_MONOTONIC
é explicado em: Diferença entre CLOCK_REALTIME e CLOCK_MONOTONIC?fonte
Talvez a diferença mais significativa seja o fato de que o ponto de partida
std::chrono:system_clock
é 1.1.1970, a chamada época do UNIX. Por outro lado,std::chrono::steady_clock
normalmente para o tempo de inicialização do seu PC e é mais adequado para medir intervalos.fonte