리눅스에서 시간 측정-시간 대 시계 대 getrusage 대 clock_gettime 대 gettimeofday 대 timespec_get?


148

타이밍 기능 중, time, clock getrusage, clock_gettime, gettimeofday그리고 timespec_get, 나는 그들이 구현하는 방법을 명확하게 이해하고 싶은 어떤 상황에서 내가 그들을 사용해야 알기 위해 자신의 반환 값 것입니다.

먼저 wall-clock 값 을 반환하는 함수를 프로세스 또는 스레드 값을 반환하는 함수와 비교 하여 분류해야 합니다 . 전달 된 매개 변수 에 따라 gettimeofday벽시계 값, clock_gettime벽시계 값 또는 프로세스 또는 스레드 값을 리턴 Clock합니다. getrusageclock공정 값을 반환합니다.

그런 다음 두 번째 질문은 이러한 기능의 구현과 결과적으로 정확성에 관한 것입니다. 이러한 기능을 사용하는 하드웨어 또는 소프트웨어 메커니즘

것으로 보인다 getrusage용도에만 커널 틱 (보통 긴 1MS)과 결과적으로는 MS보다 더 정확하지 않을 수 있습니다. 맞아? 그런 다음이 getimeofday기능은 사용 가능한 가장 정확한 기본 하드웨어를 사용하는 것 같습니다. 결과적으로 정확도는 최신 하드웨어에서 일반적으로 마이크로 초 (API 때문에 더 이상 될 수 없음)입니다. 에 대해 무엇을 clock, "근사"에 대한 매뉴얼 페이지가 말하는, 그것은 무엇을 의미합니까? 무엇에 대해 clock_gettime, API는, 나노초에 그것이 하드웨어를 기본 것은 허용하는 경우 그렇게 정확하게 할 수 있다는 의미는 무엇입니까? 단 조성은 어떻습니까?

다른 기능이 있습니까?

답변:


198

문제는 C와 C ++에서 사용할 수있는 몇 가지 다른 시간 함수가 있으며 그 중 일부는 구현마다 동작에 따라 다릅니다. 또한 반 답이 많이 떠 있습니다. 시계 기능 목록을 속성과 함께 컴파일하면 질문에 올바르게 대답 할 수 있습니다. 시작을 위해 우리가 찾고있는 관련 속성이 무엇인지 물어 봅시다. 귀하의 게시물을 보면 다음과 같이 제안합니다.

  • 시계는 몇시에 측정합니까? (실제, 사용자, 시스템 또는 벽시계가 아닌가?)
  • 시계의 정밀도는 무엇입니까? (s, ms, µs 이상입니까?)
  • 시계가 얼마나 많은 시간을 보낸 후? 아니면 이것을 피할 수있는 메커니즘이 있습니까?
  • 시계가 단조롭거나 시스템 시간 (NTP, 시간대, 일광 절약 시간, 사용자 등)을 변경함에 따라 변경됩니까?
  • 위의 구현 방식은 어떻게 다릅니 까?
  • 특정 기능이 더 이상 사용되지 않습니까, 비표준입니까?

목록을 시작하기 전에 표준 시간대 변경, 일광 절약 시간제 변경 또는 NTP에 의해 벽시계가 동기화 된 경우에는 벽시계 시간이 사용하기에 적합한 시간이 아니라는 점을 지적하고 싶습니다. 이벤트를 예약하거나 성능을 벤치마킹하는 데 시간을 사용한다면 이러한 것들 중 어느 것도 좋지 않습니다. 벽에 붙은 시계 (또는 데스크탑)라는 이름만으로도 정말 좋습니다.

리눅스와 OS X의 시계에서 지금까지 찾은 내용은 다음과 같습니다.

  • time() OS에서 벽시계 시간을 초 단위로 반환합니다.
  • clock()사용자와 시스템 시간의 합계를 반환하는 것 같습니다. C89 이상에 존재합니다. 한 번에 이것은 사이클 단위의 CPU 시간이되어야했지만 POSIX와 같은 최신 표준 은 CLOCKS_PER_SEC가 1000000이어야하므로 가능한 최대 정밀도는 1µs입니다. 내 시스템의 정밀도는 실제로 1 µs입니다. 이 클럭은 일단 최고가되면 랩핑됩니다 (이것은 일반적으로 ~ 2 ^ 32 틱 후에 발생하며 1MHz 클럭에 대해서는 그리 오래 걸리지 않습니다). man clockglibc 2.18부터는 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...)Linux에서 구현된다고 말합니다 .
  • clock_gettime(CLOCK_MONOTONIC, ...)나노초 해상도를 제공하며 단조입니다. '초'와 '나노초'는 각각 32 비트 카운터에 별도로 저장되어 있다고 생각합니다. 따라서 수십 년의 가동 시간 후에 랩 어라운드가 발생합니다. 이것은 매우 좋은 시계처럼 보이지만 불행히도 OS X에서는 아직 사용할 수 없습니다. POSIX 7 은 선택적 확장으로 설명 CLOCK_MONOTONIC합니다 .
  • getrusage()내 상황에 가장 적합한 것으로 판명되었습니다. 사용자 및 시스템 시간을 개별적으로보고하며 둘러싸이지 않습니다. 내 시스템의 정밀도는 1 µs이지만 Linux 시스템 (GCC 4.1.2의 Red Hat 4.1.2-48)에서도 테스트했으며 정밀도는 1ms에 불과했습니다.
  • gettimeofday()벽시계 시간을 (명 목적으로) µs 정밀도로 반환합니다. 내 시스템에서이 클럭의 정밀도는 µs 인 것처럼 보이지만 "시스템 클럭의 해상도는 하드웨어에 따라 다름"으로 보장되지 않습니다 . POSIX.1-2008 은 말합니다 . "응용 프로그램은 더 이상 사용되지 않는 clock_gettime()기능 대신이 gettimeofday()기능을 사용해야합니다." Linux x86 은 시스템 호출로 구현합니다 .
  • mach_absolute_time()OS X에서 매우 높은 해상도 (ns) 타이밍을위한 옵션입니다. 내 시스템에서는 실제로 ns 해상도를 제공합니다. 원칙적으로이 클럭은 랩핑되지만 64 비트 부호없는 정수를 사용하여 ns를 저장하므로 랩핑은 실제로 문제가되지 않습니다. 이식성은 의심 스럽다.
  • Linux와 OS X에서 ns 정밀도를 얻기 위해 Linux에서 컴파일 할 때 clock_gettime을 사용하거나 OS X에서 컴파일 할 때 Mach 타이머를 사용하는 이 스 니펫 을 기반으로 한 하이브리드 함수작성했습니다.

위의 모든 사항은 달리 지정된 경우를 제외하고 Linux 및 OS X 모두에 존재합니다. 위의 "내 시스템"은 MacPorts의 GCC 4.7.2와 함께 OS X 10.8.3을 실행하는 Apple입니다.

마지막으로 위의 링크 외에 도움이되는 참조 목록이 있습니다.


업데이트 : OS X clock_gettime의 경우 10.12 (Sierra)부터 구현되었습니다. 또한 POSIX 및 BSD 기반 플랫폼 (OS X와 ​​같은)은 모두 rusage.ru_utime구조체 필드를 공유합니다 .


맥 OS X가없는 clock_gettime,의 따라서 사용 gettimeofday()보다 더 다양한 조금 인clock_gettime()
bobobobo

1
times()이슈 1 이후 POSIX에 존재하는 (s)에 대해서는 언급하지 않았습니다 . GNU / Linux에 관한 문제 : clock (3) 매뉴얼 페이지에 따르면 clock()glibc 2.17 및 이전 버전의 페이지 가 그 위에 구현되었지만 개선되었습니다. 정밀도는 이제 clock_gettime(CLOCK_PROCESS_CPUTIME_ID,...)POSIX에도 지정되지만 선택 사항 인 위에 구현됩니다 .
vinc17

2
@starflyer 클럭의 정밀도는 클럭을 폴링하는 데 걸리는 시간에 의해 부분적으로 제한됩니다. 시계를 호출하고 돌아 오는 데 1 µs가 걸리면 발신자의 관점에서 시계가 1 µs 씩 "off"가되기 때문입니다. 이는 매우 정확한 클럭도 지연 시간이 짧아야한다는 것을 의미합니다. 따라서 일반적으로 사용자가 이야기하는 절충안이 없습니다. 가장 저렴한 시계도 가장 정확합니다.
Douglas B. Staple

3
또한 대부분의 시계는 그들이 것으로 간주되는 경우에도, 일광 절약 시간 / 시간대 걱정하지 않는다 벽 시계 . 모두 timegettimeofday반환, 요즘 이상, 초, 에포크 (유닉스 타임 스탬프 일명). 시간대 / DST와 무관합니다. 윤초는 또 다른 이야기입니다 ...
Zulan

2
Android 사용자의 경우 시계와 함께 앱이 일시 중지 될 수 있으므로 CLOCK_MONOTONIC를 사용하면 문제가 발생할 수 있습니다. 이를 위해 Android는 ioctl을 통해 액세스 할 수있는 ANDROID_ALARM_ELAPSED_REALTIME 타이머를 추가했습니다. 이들 및 기타 일시 중단 관련 정보에 대한 일부 정보는 여기를 참조하십시오.
Itay Bianco

17

C11 timespec_get

https://stackoverflow.com/a/36095407/895245의 사용 예

반환되는 최대 정밀도는 나노초이지만 실제 정밀도는 구현이 정의되어 있으며 더 작을 수 있습니다.

CPU 사용량이 아닌 월 시간을 반환합니다.

glibc 2.21은 아래에 구현하고 다음으로 sysdeps/posix/timespec_get.c직접 전달합니다.

clock_gettime (CLOCK_REALTIME, ts) < 0)

clock_gettimeCLOCK_REALTIMEPOSIX 있습니다 http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html , 그리고 man clock_gettime당신이 당신의 프로그램이 실행되는 동안 일부 시스템 시간 설정을 변경하면이 측정이 불연속이있을 수 있다고 말한다.

C ++ 11 크로노

우리가 그것을 다루었으므로, 이것들도 다룰 것입니다 : http://en.cppreference.com/w/cpp/chrono

GCC 5.3.0 (C ++ stdlib는 GCC 소스에 있음) :

  • high_resolution_clock 에 대한 별칭입니다 system_clock
  • system_clock 사용 가능한 다음 중 첫 번째로 전달합니다.
    • clock_gettime(CLOCK_REALTIME, ...)
    • gettimeofday
    • time
  • steady_clock 사용 가능한 다음 중 첫 번째로 전달합니다.
    • clock_gettime(CLOCK_MONOTONIC, ...)
    • system_clock

질문 : std :: system_clock과 std :: steady_clock의 차이점은 무엇입니까?

CLOCK_REALTIMEvs CLOCK_MONOTONIC: CLOCK_REALTIME과 CLOCK_MONOTONIC의 차이점은 무엇입니까?


1
일반적인 구현을 이해하지 못하는 훌륭한 답변. 그것이 사람들이 정말로 알아야 할 것입니다.
Celess
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.