지속가능티끌/C . C++2016. 2. 20. 19:31

 

 

개요

 

고정밀 시각, 시간측정용  std::chrono 는 "C++11" 이후 도입, Visual C++ 2012 이후 도입.


용어. 

시각 : time point.

시간 : time interval, 2개 시각의 간격.


특징

- 고정밀(최소 시간단위 : 나노초), 편리기능 함수들.

- 주요 클래스 : duration, time_point

- 주요구조체 : system_clock, steady_clock

- steady_clock 특징 

Visual C++ 에서는 내부적으로 QueryPerformanceCounter 로 구현되어있음.

monotonic. 늦게 호출된 now() 가 먼저 호출된 now() 이상의 값(같거나 더 큰 값)이 나온다는 의미.



헤더파일 #include <chrono>

 


 

 

 

 


cpp reference 사이트의


chrono : http://en.cppreference.com/w/cpp/header/chrono

time_point : http://en.cppreference.com/w/cpp/chrono/time_point

duration  : http://en.cppreference.com/w/cpp/chrono/duration 


 

 

 

 

 

코드예-1

 

 

현재시각 구하기. (epoch이후의 경과시간)


std::chrono::system_clock::time_point tp_Now = std::chrono::system_clock::now();  

std::chrono::system_clock::duration duEpoch = tp_Now.time_since_epoch();

int64_t TimeIntervalEpoch_64 = std::chrono::duration_cast<std::chrono::nanoseconds>duEpoch.count();


설명.

1.  now() 함수 호출한 시점의 "시각"이  자료형 time_point 변수 tp_Now 에 저장된다. 

2. 상기1에서 "시각"이라함은 epoch(UTC 1970년 1월 1일 0시0분0초 시점) 이후 now 호출한 시점까지의 나노초 단위의 경과시간.

3. 상기2의 epoch이후의 경과시간은 time_point 의 멤버 함수 time_since_epoch() 호출하여 duration 형 변수 duEpoch로 받았다.

4. duEpoch.count() 함수 호출로 64비트 정수형 변수 TimeIntervalEpoch_64 으로 받았다. 


주의사항:  nanoseconds 로 명시적 형변환 해야만 정확한 값을 받을 수 있음. nanoseconds 로 형변환 하지 않은 경우엔 반환값이 나노도 아니고, 마이크로 초도 아닌 나노초 기준 100으로 나눈값이 반환됨.

nanoseconds 로 명시적 형변환 한 경우 : epoch 이후 경과한 정확한 나노초 : 1456136176997090600 

명시적 형변환 없이 duEpoch.count(); 로 그냥 받은 경우 : 14561361769970906  상기 대비 100으로 나눈값임.



코드의 특정 처리구간 시간격 구하기.


1
2
3
4
5
6
7
8
9
10
11
12
13
std::chrono::steady_clock::time_point tp_start = std::chrono::steady_clock::now();  
 
... 이것저것 처리구간.
 
std::chrono::steady_clock::time_point tp_end = std::chrono::steady_clock::now();  
 
 
std::chrono::nanoseconds diff_nano = tp_end - tp_start; // 나노(10^-9)초 단위로 차이 구한다.
 
std::chrono::microseconds diff_micro = duration_cast<microseconds>(tp_end - tp_start); // 마이크로(10^-6)초 단위로 차이 구한다.
 
std::chrono::miliseconds diff_mili = duration_cast<miliseconds>(tp_end - tp_start); // 밀리(10^-3)초 단위로 차이 구한다.
 



 

 

 

 

 

코드예-2. 당일 0시 이후 현재까지 경과시간 나노초 단위로 받기.

 

아래 코드에 사용된 std::time_t, std:tm 상세 보기 : http://igotit.tistory.com/673

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
        std::time_t tNow = std::time(NULL); // epoch(1970년 1월1일0시0분0초) 이후 초단위.
 
    std::tm tmYMDHMS; // 현재일자의 0시0분0초 기록할 변수.
 
    tmYMDHMS.tm_year = std::localtime(&tNow)->tm_year;
    tmYMDHMS.tm_mon = std::localtime(&tNow)->tm_mon;
    tmYMDHMS.tm_mday = std::localtime(&tNow)->tm_mday;
    tmYMDHMS.tm_hour = 0; 
    tmYMDHMS.tm_min = 0;
    tmYMDHMS.tm_sec = 0; 
 
    std::time_t theDay000 = std::mktime(&tmYMDHMS); //tmYMDHMS를 time_t 형식으로 변경. 
 
    // time_point 형으로 당일0시0분0초 받음. 
    std::chrono::system_clock::time_point tpDay000 = std::chrono::system_clock::from_time_t(theDay000); 
    
    // time_point 형으로 현재 시각(epoch 이후 경과시간)받음. 
    std::chrono::system_clock::time_point tpNow = std::chrono::system_clock::now();
 
    std::cout << "오늘 0시 이후 경과      시 : "
        << std::chrono::duration_cast<std::chrono::hours>(tpNow - tpDay000).count() << '\n';
 
    std::cout << "오늘 0시 이후 경과      분 : "
        << std::chrono::duration_cast<std::chrono::minutes>(tpNow - tpDay000).count() << '\n';
 
    std::cout << "오늘 0시 이후 경과      초 : "
        << std::chrono::duration_cast<std::chrono::seconds>(tpNow - tpDay000).count() << '\n';
 
    std::cout << "오늘 0시 이후 경과 밀리 초 : "
        << std::chrono::duration_cast<std::chrono::milliseconds>(tpNow - tpDay000).count() << '\n';
 
    std::cout << "오늘 0시 이후 경과 마이크로초 : " 
        << std::chrono::duration_cast<std::chrono::microseconds>(tpNow - tpDay000).count() << '\n';
 
    std::cout << "오늘 0시 이후 경과 나노  초 : "
        << std::chrono::duration_cast<std::chrono::nanoseconds>(tpNow - tpDay000).count() << '\n';

실행결과.

오늘 0시 이후 경과      시 : 23
오늘 0시 이후 경과      분 : 1415
오늘 0시 이후 경과      초 : 84957
오늘 0시 이후 경과 밀리 초 : 84957784
오늘 0시 이후 경과 마이크로초 : 84957784079
오늘 0시 이후 경과 나노  초 : 84957784079500 

 

 


 


 

코드예-3. 실수형으로 받기.

 
상기 코드예-2의 마지막에 아래 코드 추가.

1
2
3
4
5
6
7
8
9
10
    using FpFloatMilliseconds = std::chrono::duration<float, std::chrono::milliseconds::period>;
    using FpDoubleMilliseconds = std::chrono::duration<double, std::chrono::milliseconds::period>;
 
    float f_ms = FpFloatMilliseconds(tpNow - tpDay000).count();
    double d_ms = FpDoubleMilliseconds(tpNow - tpDay000).count();
 
    printf("float 밀리초 :%f\n", f_ms);
    printf("double 밀리초 :%f\n", d_ms);
 
 
 
실행결과.

오늘 0시 이후 경과      시 : 0
오늘 0시 이후 경과      분 : 26
오늘 0시 이후 경과      초 : 1570
오늘 0시 이후 경과 밀리 초 : 1570301
오늘 0시 이후 경과 마이크로초 : 1570301927
오늘 0시 이후 경과 나노  초 : 1570301927700
float 밀리초 :1570302.000000
double 밀리초 :1570301.927700


 


 


 본 글이 포함된 상위 정리 장소.

 

 Visual Studio/VC++/C/C# 활용정리 -> http://igotit.tistory.com/11

 

 

 

///672.

 

Posted by 리치굿맨

댓글을 달아 주세요