std::system_clock
과 의 차이점은 무엇입니까 std::steady_clock
? (다른 결과 / 동작을 보여주는 예제 사례가 좋습니다).
내 목표가 (벤치 마크와 같은) 함수의 실행 시간을 정확하게 측정하는 것이라면 std::system_clock
, std::steady_clock
과 사이에서 가장 좋은 선택은 std::high_resolution_clock
무엇일까요?
std::system_clock
과 의 차이점은 무엇입니까 std::steady_clock
? (다른 결과 / 동작을 보여주는 예제 사례가 좋습니다).
내 목표가 (벤치 마크와 같은) 함수의 실행 시간을 정확하게 측정하는 것이라면 std::system_clock
, std::steady_clock
과 사이에서 가장 좋은 선택은 std::high_resolution_clock
무엇일까요?
system_clock
Windows에서는 안정적이지 않습니다. Windows에서 시스템 시간은 충분한 권한이있는 사용자에 의해 임의의 값으로 변경 될 수 있습니다. 또한 시간 동기화 서비스는 필요한 경우 시스템 시간을 뒤로 조정할 수 있습니다. 대부분의 다른 플랫폼에는 시스템 시간을 조정할 수있는 유사한 기능이 있습니다.
답변:
N3376에서 :
20.11.7.1 [time.clock.system] / 1 :
클래스의 객체는
system_clock
시스템 전체 실시간 시계의 벽시계 시간을 나타냅니다.
20.11.7.2 [time.clock.steady] / 1 :
클래스의 객체는 물리적 시간이 진행됨에 따라
steady_clock
값이time_point
감소하지 않고time_point
실시간에 비해 일정한 속도로 진행 되는 시계를 나타냅니다 . 즉, 시계가 조정되지 않을 수 있습니다.
20.11.7.3 [time.clock.hires] / 1 :
클래스의 객체는
high_resolution_clock
틱주기가 가장 짧은 시계를 나타냅니다. 또는high_resolution_clock
의 동의어 일 수 있습니다 .system_clock
steady_clock
예를 들어, 시스템 전체 시계는 일광 절약 시간과 같은 영향을받을 수 있으며,이 시점에서 미래의 특정 시점에 나열된 실제 시간은 실제로 과거 시간이 될 수 있습니다. (예를 들어 미국에서는 하강 시간이 1 시간 뒤로 이동하므로 같은 시간이 "두 번"경험됩니다.) 그러나 steady_clock
그러한 일에 영향을받는 것은 허용되지 않습니다.
이 경우 "정상"에 대해 생각하는 또 다른 방법은 20.11.3 [time.clock.req] / 2의 표에 정의 된 요구 사항입니다.
표 59
C1
및C2
나타낸다 시계 타입.t1
과t2
에 의해 반환 된 값입니다C1::now()
반환 호출이 곳t1
호출이 반환하기 전에 발생t2
하고 이러한 호출 모두 전에 발생은C1::time_point::max()
. [참고 :이 수단C1
사이의 주위에 포장하지 않았다t1
및t2
. —end note]표현식 :
C1::is_steady
반환 값 :const bool
작동 의미론 : 이 항상 참이고 클록 틱 사이의 시간이 일정true
하다면t1 <= t2
, 그렇지 않으면false
.
그것이 그들의 차이점에 대한 모든 표준입니다.
벤치마킹을하려는 경우 가장 좋은 방법은 일 것 std::high_resolution_clock
입니다. 플랫폼 QueryPerformanceCounter
에서이 시계에 고해상도 타이머 (예 : Windows)를 사용할 가능성이 높기 때문 입니다. 그러나 벤치마킹하는 경우 플랫폼마다 다르게 처리하므로 벤치 마크에 플랫폼 별 타이머를 사용하는 것이 좋습니다. 예를 들어, 일부 플랫폼은 프로그램에 필요한 실제 클럭 틱 수를 결정하는 수단을 제공 할 수 있습니다 (동일한 CPU에서 실행되는 다른 프로세스와 무관). 더 좋은 방법은 실제 프로파일 러에 손을 대고 사용하는 것입니다.
steady_clock
와 system_clock
여기 의 차이 .
system_clock
UTC 일 필요는 없습니다 .
Billy는 내가 완전히 동의하는 ISO C ++ 표준을 기반으로 훌륭한 답변을 제공했습니다. 그러나 이야기의 또 다른 측면이 있습니다. 지금은 인기있는 컴파일러를 구현할 때 이러한 클럭간에 실제로 차이가없는 것 같습니다.
gcc 4.8 :
#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
...
#else
typedef system_clock steady_clock;
#endif
typedef system_clock high_resolution_clock;
Visual Studio 2012 :
class steady_clock : public system_clock
{ // wraps monotonic clock
public:
static const bool is_monotonic = true; // retained
static const bool is_steady = true;
};
typedef system_clock high_resolution_clock;
gcc의 경우 확인 is_steady
하고 그에 따라 행동하는 것만으로도 안정된 시계를 다루고 있는지 확인할 수 있습니다 . 그러나 VS2012는 여기에서 약간 속임수를 쓰는 것 같습니다 :-)
고정밀 클럭이 필요한 경우 C ++ 11 공식 클럭 인터페이스를 준수하는 자체 클럭을 작성하고 구현이 따라 잡을 때까지 기다리는 것이 좋습니다. 코드에서 직접 OS 특정 API를 사용하는 것보다 훨씬 더 나은 접근 방식입니다. Windows의 경우 다음과 같이 할 수 있습니다.
// Self-made Windows QueryPerformanceCounter based C++11 API compatible clock
struct qpc_clock {
typedef std::chrono::nanoseconds duration; // nanoseconds resolution
typedef duration::rep rep;
typedef duration::period period;
typedef std::chrono::time_point<qpc_clock, duration> time_point;
static bool is_steady; // = true
static time_point now()
{
if(!is_inited) {
init();
is_inited = true;
}
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
return time_point(duration(static_cast<rep>((double)counter.QuadPart / frequency.QuadPart *
period::den / period::num)));
}
private:
static bool is_inited; // = false
static LARGE_INTEGER frequency;
static void init()
{
if(QueryPerformanceFrequency(&frequency) == 0)
throw std::logic_error("QueryPerformanceCounter not supported: " + std::to_string(GetLastError()));
}
};
Linux의 경우 훨씬 더 쉽습니다. 의 man 페이지를 읽고 clock_gettime
위의 코드를 수정하십시오.
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
그런 다음 CLOCK_REALTIME
vs CLOCK_MONOTONIC
설명 : CLOCK_REALTIME과 CLOCK_MONOTONIC의 차이점?