Search

[ VC11-C++11 ] chrono - clock 클래스

C++0x 2012. 8. 14. 09:00 Posted by 알 수 없는 사용자

이번은 chrono clock 클래스에 대해서 간단하게 설명 하겠습니다.

앞의 글들을 보신 분 들은 아시겠지만 이미 clock 클래스를 사용하고 있었습니다.

 

다만 저는 현재까지는 system_clock 이라는 클래스만을 사용하고 있었습니다.

 

chrono에는 system_clock뿐만 아닌 steady_clock high_resolution_clock이 있습니다.

 

 

namespace std {

 

namespace chrono {

 

  class system_clock;

 

}}

 

 

namespace std {

 

namespace chrono {

 

  class steady_clock;

 

}}

 

   

 

namespace std {

 

namespace chrono {

 

  class high_resolution_clock;

 

}}

 

 

system_clock는 가장 일반적으로 사용하는 것으로 시스템 시간을 표현하기 위한 시간입니다.

그리고 C 런타임의 time_t와 호환성을 가지고 있습니다.

 

멤버 중에 to_time_t from_time_t가 있는데 이름을 보면 알 수 있듯이

to_time_t system_clock::time_point time_t로 변환하고,

from_time_t time_t system_clock::time_point로 변환 합니다.

 

 

// to_time_t

system_clock::time_point CurTime = system_clock::now();

std::time_t t = system_clock::to_time_t(CurTime);

 

// from_time_t

std::time_t t = time(NULL);

system_clock::time_point CurTime = system_clock::from_time_t(t);

 

 

steady_clock은 물리적인 시간처럼 결코 역행하지 않는 시간을 나타내기 위한 시간입니다.

이 말은 steady_clock 이외의 clock 클래스는 time_point를 얻은 후 os에서 날짜를 과거를 되돌린 후 time_point을 얻으면 앞에 얻은 시간보다 과거의 시간이 얻어지는데 steady_clock에서는 절대 그렇지 않습니다. 그래서 시간의 흐름이 바뀌지 않는 시간을 얻고 싶을 때는 steady_clock을 사용합니다.

 

 

high_resolution_clock는 해당 플랫폼(Windows 또는 Linux )에서 가장 짧은 단위의 시간입니다.

이 클래스는 system_clock steady_clock의 다른 별칭으로 정의되기도 합니다.

 

 

 

보통 프로그래밍에서 아주 고해상도의 시간 단위가 아닌 경우 대부분 GetTickCount() 함수를 사용했는데(Windows에서) 앞으로는 더 간단하고 다양한 표현 방법으로 시간을 다룰 수 있는 chrono를 꼭 사용해 보시기 바랍니다^^

 

[ VC11-C++11 ] chrono - 시간 계산

C++0x 2012. 8. 7. 09:00 Posted by 알 수 없는 사용자

<예제.2>에서 보았듯이 chrono는 다양한 정밀도 타입으로 시간을 표시할 수 있습니다.

 

그리고 각 시간 정밀도 타입 별로 생성할 때 미리 값을 설정할 수 있습니다.

 

std::chrono::hours H1(1);

std::chrono::seconds S1(10);

std::chrono::milliseconds MILS1(100);

 


또한 이 시간 타입을 서로 연산할 수도 있습니다.

 

std::chrono::hours H1(1);

std::chrono::hours H2(2);

std::chrono::hours H3 = H1 + H2;

 


물론 다른 시간 타입을 연산할 수도 있습니다

 

std::chrono::seconds S1(10);

std::chrono::milliseconds MILS1(100);

std::chrono::milliseconds MILS2 = S1 + MILS1;

 

다른 시간 타입을 연산할 때 주의할 점이 있습니다. 아래처럼

 

std::chrono::milliseconds MILS2 = S1 + MILS1;

 

의 경우는 초와 밀리초라는 서로 다른 타입을 더하지만 값을 저장하는 타입이 밀리초이기 때문에 잃어버리는 값이 발생하지 않으므로 연산에 문제가 없습니다.

 

그러나 아래와 같이

std::chrono:: seconds S2 = S1 + MILS1;

로 하는 경우는 밀리초 부분을 잃어버리게 되기 때문에 컴파일 에러가 발생합니다.

 

이런 경우는 명시적으로 형 변환을 시켜줘야 합니다.

 

std::chrono::seconds S2 = std::chrono::duration_cast< std::chrono::seconds >(S1 + MILS1);

 

 

< 예제. 3 >

#include <chrono>

#include <iostream>

 

int main()

{

    {

        std::chrono::hours H1(1); // 1시간

       

        std::cout << "H1(1) : " << H1.count() << std::endl;

        

        std::chrono::seconds S1(10);

        std::chrono::seconds S2(120);

 

        std::cout << "S1(10) : " << S1.count() << std::endl;

        std::cout << "S2(120) : " << S2.count() << std::endl;

    }

 

    {

        std::chrono::hours H1(1);

        std::chrono::hours H2(2);

        std::chrono::hours H3 = H1 + H2;

 

        std::cout << "H1 + H2 = : " << H3.count() << std::endl;

  

        std::chrono::seconds S1(10);

        std::chrono::milliseconds MILS1(100);

        std::chrono::milliseconds MILS2 = S1 + MILS1;

 

        std::cout << "S1 + MILS1 = : " << MILS2.count() << std::endl;

  

        std::chrono::seconds S2 = std::chrono::duration_cast< std::chrono::seconds >(S1 + MILS1);

 

        std::cout << "S1 + MILS1 = : " << S2.count() << std::endl;

    }

 

    return 0;

}

 

< 실행 결과 >


[ VC11-C++11 ] chrono - 시간 측정하기

C++0x 2012. 7. 31. 10:41 Posted by 알 수 없는 사용자

chrono는 C++11에서 새로 추가된 시간 라이브러리입니다. 기존의 C 런타임에서 제공하는 time 함수에 비해서 다양한 기능이 있고, 사용이 쉽고 정밀도는 훨씬 높습니다. time 함수는 초 단위의 값만 측정할 수 있는 것에 비해 chrono는 나노 밀리 초 단위도 측정할 수 있습니다.

 

현재의 C++(C++03)에서는 초 단위보다 더 정밀한 단위로 시간을 측정할 때는 OS에서 제공하는 API를 사용해야 했는데 chrono를 사용하면 OS 독립적으로 높은 단위의 시간을 측정할 수 있습니다.

 

VC10에서는 chrono가 들어가지 않았지만 이번 VC11에서 chrono STL에 들어갔습니다. 만약 VC11을 사용하지 못하는 경우라면 Boost 라이브러리를 사용하면 사용할 수 있습니다.

 

chrono를 사용하면 특정 시간 구간에 걸린 시간을 초, 밀리 초, 나노 초 단위로 얻을 수 있으며 또 시간끼리 연산을 할 수 있습니다

 

 

 

chrono 사용 방법

 

chrono를 사용하기 위해서는 아래의 헤더 파일을 추가합니다.

#include <chrono>

 

 

chrono에 대한 자세한 설명에 앞서 어떤 기능인지 좀 더 쉽게 알 수 있도록 예제를 하나 보여드리겠습니다. 아래의 예제는 어떤 함수의 성능을 측정하기 위해서 chrono를 사용했습니다.

 

 

< 예제. 1 >

#include <chrono>

#include <iostream>

#include <cmath>

 

 

void Test()

{

           for ( long i = 0; i < 10000000; ++i )

           {

                     std::sqrt( 123.456L );

           }

}

 

 

 

int main()

{

 

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

 

    Test();

          

    std::chrono::duration<double> sec = std::chrono::system_clock::now() - start;

 

    std::cout << "Test() 함수를 수행하는 걸린 시간() : " << sec.count() << " seconds" << std::endl;

 

    return 0;

}

 

< 실행 결과 >


 

<예제.1>에서는 std::chrono::system_clock::now()을 사용하여 현재 시간을 얻습니다.

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

여기서 time_point 타입은 시간 상의 한 축을 뜻합니다.

 

 

 

이후 Test() 함수를 실행한 후 다시 현재 시간을 얻은 후 Test()를 시작하기 전에 저장한 현지 시간을 빼면 Test()를 수행하는 걸린 시간을 얻을 수 있습니다.

 

std::chrono::duration<double> sec = std::chrono::system_clock::now() - start;

  

* std::chrono::system_clock::now()에 의해서 얻는 시간의 초기 시간은 1970년 입니다.

 

 

 

시간 단위

chrono는 경과 시간을 계산할 때 다양한 시간 타입으로 계산할 수 있습니다.

 

<예제.1>에서는 초 단위의 정밀도로 소수점까지 표시할 수 있었습니다.

 

std::chrono::duration<double> sec = std::chrono::system_clock::now() - start;

 

그런데 보통은 소수점이 나오는 결과 값보다는 정수로 나오는 값을 사용하는 경우가 많을 것입니다.

 

 

chrono에서는 경과 시간을 나타내는 클래스는 duration입니다.

duration 6개의 시간 단위를 지원합니다.

 

std::chrono::nanoseconds  // 나노 세컨드. 10억분의 1

std::chrono::microseconds // 마이크로 세컨드. 100만분의 1

std::chrono::milliseconds   // 밀리 세컨드. 1000분의 1

std::chrono::seconds        //

std::chrono::minutes         //

std::chrono::hours           //

 

<예제.1>을 수정하여 위에 열거한 chrono의 다양한 단위를 사용하여 시간 측정을 해 보겠습니다.

 

< 예제. 2 >

#include <chrono>

#include <iostream>

#include <cmath>

 

 

void Test()

{

           for ( long i = 0; i < 10000000; ++i )

           {

                     std::sqrt( 123.456L );

           }

}

 

int main()

{

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

          

    Test();

 

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

 

 

 

    std::chrono::duration<double> DefaultSec = EndTime - StartTime;

 

    std::chrono::nanoseconds nano = EndTime - StartTime;

 

    std::chrono::microseconds micro = std::chrono::duration_cast<std::chrono::microseconds>(EndTime - StartTime);

 

    std::chrono::milliseconds mill   = std::chrono::duration_cast<std::chrono::milliseconds>(EndTime - StartTime);

 

    std::chrono::seconds sec                   = std::chrono::duration_cast<std::chrono::seconds>(EndTime - StartTime);

 

    std::chrono::minutes min                  = std::chrono::duration_cast<std::chrono::minutes>(EndTime - StartTime);

 

    std::chrono::hours hour                              = std::chrono::duration_cast<std::chrono::hours>(EndTime - StartTime);

 

 

 

    std::cout << "Test() 함수를 수행하는 걸린 시간 : " << DefaultSec.count() << " default" << std::endl;

 

    std::cout << "Test() 함수를 수행하는 걸린 시간 : " << nano.count() << " nanoseconds" << std::endl;

 

    std::cout << "Test() 함수를 수행하는 걸린 시간 : " << micro.count() << " microseconds" << std::endl;

 

    std::cout << "Test() 함수를 수행하는 걸린 시간 : " << mill.count() << " milliseconds" << std::endl;

 

    std::cout << "Test() 함수를 수행하는 걸린 시간 : " << sec.count() << " seconds" << std::endl;

 

    std::cout << "Test() 함수를 수행하는 걸린 시간 : " << min.count() << " minutes" << std::endl;

 

    std::cout << "Test() 함수를 수행하는 걸린 시간 : " << hour.count() << " hour" << std::endl;

          

    return 0;

}

 

< 실행 결과 >