c - gettimeofday - linux time()




Medir o tempo no Linux-tempo vs relógio vs getrusage vs clock_gettime vs gettimeofday vs timespec_get? (2)

Entre as funções de time , time , clock getrusage , clock_gettime , gettimeofday e timespec_get , eu quero entender claramente como eles são implementados e quais são seus valores de retorno para saber em qual situação eu tenho que usá-los.

Primeiro, precisamos classificar as funções que retornam valores de relógio de parede a funções de retorno de processos ou valores de threads . gettimeofday retorna valor de relógio de parede, clock_gettime retorna valor de relógio de parede ou valores de processo ou threads, dependendo do parâmetro Clock passado para ele. getrusage e clock retornam os valores do processo.

Em seguida, a segunda questão diz respeito à implementação dessas funções e, como conseqüência, a sua precisão. Qual mecanismo de hardware ou software essas funções usam?

Parece que o getrusage usa apenas o tick do kernel (geralmente 1 ms de comprimento) e, como conseqüência, não pode ser mais preciso do que o ms. Está certo? Então a função getimeofday parece usar o hardware subjacente mais preciso disponível. Como conseqüência, sua precisão é geralmente o microssegundo (não pode ser mais por causa da API) no hardware recente. E quanto ao clock , a página man fala sobre "aproximação", o que isso significa? E quanto a clock_gettime , a API está em nanossegundos, isso significa que ela pode ser tão precisa se o hardware subjacente permitir? E quanto à monotonicidade?

Existem outras funções?


O problema é que existem várias funções de tempo diferentes disponíveis em C e C ++, e algumas delas variam em comportamento entre implementações. Há também muitas meias respostas flutuando. Compilar uma lista de funções do relógio junto com suas propriedades responderia a pergunta corretamente. Para começar, vamos perguntar quais são as propriedades relevantes que estamos procurando. Olhando para o seu post, sugiro:

  • Que horas são medidas pelo relógio? (real, usuário, sistema ou, esperançosamente, não, relógio de parede?)
  • Qual a precisão do relógio? (s, ms, µs ou mais rápido?)
  • Depois de quanto tempo o relógio envolve? Ou existe algum mecanismo para evitar isso?
  • O relógio é monotônico ou será alterado com alterações no horário do sistema (via NTP, fuso horário, horário de verão, pelo usuário, etc.)?
  • Como os itens acima variam entre implementações?
  • A função específica é obsoleta, não padrão, etc.?

Antes de iniciar a lista, gostaria de salientar que o relógio de parede raramente é o momento certo de usar, enquanto ele muda com as alterações de fuso horário, o horário de verão é alterado ou se o relógio de parede é sincronizado pelo NTP. Nenhuma dessas coisas é boa se você estiver usando o tempo para agendar eventos ou para avaliar o desempenho. É bom apenas para o que o nome diz, um relógio na parede (ou desktop).

Aqui está o que eu encontrei até agora para relógios no Linux e OS X:

  • time() retorna a hora do relógio do sistema operacional, com precisão em segundos.
  • clock() parece retornar a soma do tempo do usuário e do sistema. Está presente em C89 e posterior. Ao mesmo tempo, esse era o tempo de CPU em ciclos, mas os padrões modernos, como o POSIX, exigem CLOCKS_PER_SEC como 1000000, dando uma precisão máxima possível de 1 µs. A precisão no meu sistema é de fato 1 µs. Este relógio é colocado em funcionamento uma vez terminado (isso normalmente acontece após ~ 2 ^ 32 carrapatos, o que não é muito longo para um clock de 1 MHz). man clock diz que desde o glibc 2.18 é implementado com clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) no Linux.
  • clock_gettime(CLOCK_MONOTONIC, ...) fornece resolução de nanossegundos, é monótono. Eu acredito que os 'segundos' e 'nanossegundos' são armazenados separadamente, cada um em contadores de 32 bits. Assim, qualquer wrap-around ocorreria após muitos anos de tempo de atividade. Parece um bom relógio, mas infelizmente ainda não está disponível no OS X. O POSIX 7 descreve o CLOCK_MONOTONIC como uma extensão opcional .
  • getrusage() acabou por ser a melhor escolha para a minha situação. Ele relata o usuário e o sistema vezes separadamente e não envolve. A precisão no meu sistema é de 1 µs, mas também testei em um sistema Linux (Red Hat 4.1.2-48 com GCC 4.1.2) e a precisão foi de apenas 1 ms.
  • gettimeofday() retorna a hora do relógio de parede com precisão (nominalmente) µs. No meu sistema este relógio parece ter precisão µs, mas isso não é garantido, porque gettimeofday() . POSIX.1-2008 diz isso . clock_gettime() "Aplicativos devem usar a função clock_gettime() invés da obsoleta função gettimeofday() ", então você deve ficar longe disso. Linux x86 e implementa-o como uma chamada de sistema .
  • mach_absolute_time() é uma opção para sincronismo de resolução muito alta (ns) no OS X. No meu sistema, isso realmente dá uma resolução ns. Em princípio, este relógio se enrola, no entanto, ele está armazenando ns usando um inteiro não assinado de 64 bits, portanto, o envolvimento não deve ser um problema na prática. Portabilidade é questionável.
  • Eu escrevi uma função híbrida baseada neste trecho que usa clock_gettime quando compilado no Linux, ou um temporizador Mach quando compilado no OS X, a fim de obter precisão de ns no Linux e OS X.

Todos os itens acima existem no Linux e no OS X, exceto onde especificado de outra forma. "Meu sistema" no acima é uma Apple rodando OS X 10.8.3 com o GCC 4.7.2 da MacPorts.

Finalmente, aqui está uma lista de referências que achei útil, além dos links acima:

Atualização : para o OS X, o clock_gettime foi implementado a partir do 10.12 (Sierra). Além disso, as plataformas baseadas em POSIX e BSD (como o OS X) compartilham o campo struct rusage.ru_utime .


C11 timespec_get

Exemplo de uso em: https://.com/a/36095407/895245

A precisão máxima possível retornada é de nanossegundos, mas a precisão real é definida pela implementação e pode ser menor.

Retorna o tempo de parede, não o uso da CPU.

O glibc 2.21 o implementa em sysdeps/posix/timespec_get.c e encaminha diretamente para:

clock_gettime (CLOCK_REALTIME, ts) < 0)

clock_gettime e CLOCK_REALTIME são POSIX http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html , e man clock_gettime diz que esta medida pode ter descontinuidades se você alterar alguma configuração de tempo do sistema enquanto seu programa é executado.

C + + 11 crono

Já que estamos nisso, vamos cobri-los também: http://en.cppreference.com/w/cpp/chrono

GCC 5.3.0 (C ++ stdlib está dentro da fonte do GCC):

  • high_resolution_clock é um alias para system_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

Perguntado em: Diferença entre std :: system_clock e std :: steady_clock?

CLOCK_REALTIME vs CLOCK_MONOTONIC : Diferença entre CLOCK_REALTIME e CLOCK_MONOTONIC?







linux-kernel