포스트

C++ 프로그램 시간 측정하기 feat. Linux

윈도우 환경에서 알고리즘 문제를 풀다보면,

내 코드가 수행하는데 얼마나 걸리는지 측정이 필요할 때가 있다

물론 컴퓨터의 성능따라 다르겠지만,

이전 코드와 비교하면서 속도가 개선되었는지는 판별 가능함

Ctime, time.h 차이?


ctime 헤더

  • ctime 헤더는 C++11 표준에서 새로 추가된 헤더
  • ctime 헤더는 time.h 헤더의 함수들을 표준화된 방식으로 제공
  • ctime 헤더는 time.h 헤더의 함수들에 비해 더 안전하고 사용하기 쉬움

time.h 헤더

  • time.h 헤더는 C 언어의 표준 헤더 파일
  • time.h 헤더는 C++ 표준에서 deprecated 됨.
  • time.h 헤더는 ctime 헤더의 함수들에 비해 더 안전하지 않고 사용하기 어려움

1. clock 함수 이용


  • ctime, time.h 헤더의 clock 함수 이용
  • clock_t clock(void) : 프로그램이 시작하고 나서부터, 프로세서가 소모한 시간을 리턴.
    • 즉, 프로그램의 실행 시작시간으로부터, 경과된 시간을 clock ticks수로 반환함
    • clock ticks 단위지만, ms와 동일함
    • ms 단위를 정수형으로 반환한다
    • CLOCKS_PER_SEC과 같이 사용하면 초단위로도 출력 가능함

사용법

1
2
3
4
5
6
7
8
9
10
11
12
13
// 측정 시작 위치 
clock_t startTime = clock(); 

/* 측정할 코드 */ 

// 측정 종료 위치 
clock_t endTime = clock(); 

// 측정 시간 계산 (ms단위) 
clock_t elapsed = endTime - startTime; 
// Second로 변환 
double timeInSecond = (double)(elapsed / CLOCKS_PER_SEC); 
// CLOCKS_PER_SEC 는 ((clock_t)1000)으로 define 되어있음

2. time 함수 이용


  • ctime, time.h 헤더의 time 함수 이용
  • [[time_t와 tm 구조체time_t]] time(null) : 현재 시간을 time_t 형으로 반환하는 함수
    • time_t 형은 1970년 1월 1일 자정 이후 경과한 초를 나타내는 정수형
    • clock()와 다르게 초 단위임
    • 밀리초 단위까지 구하는 방법은 조금 복잡하므로 다른 포스팅에서 별도로 다룸

사용법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/// 측정 시작 위치
time_t startTime = time(NULL);

/* 측정할 코드 */ 

// 측정 종료 위치 
time_t endTime = time(NULL);


// 측정 시간 계산 (ms단위) 
double result = (double)(endTime - startTime);

// Second로 변환 
double timeInSecond = (double)(elapsed / CLOCKS_PER_SEC); 
// CLOCKS_PER_SEC 는 ((clock_t)1000)으로 define 되어있음

3. 리눅스 환경은?


알아두면 좋은 정보들

  • RTC : 메인보드에 박혀있는 수은 건전지를 통해, 전원이 없어도 시간을 계산함

  • date : 부팅시 RTC정보를 받아, 리눅스에서 시간 정보 관리.

    네트워크에 연결될때 Time 서버에서 시간을 자동으로 업데이트함

  • sudo hwclock : RTC HW 장치가 가지고있는 시간 정보 값

    • 두 시간의 값이 다르다면 date → hwclock 맞춰주는 sync 작업 필요
  • rdate 패키지 이용

  • Latency 측정을 위해 시간 관련 라이브러리들을 사용함

    • 임베디드 장치라면 항상 입력, 출력 신호 있음

    • 고성능, 빠른 실시간 응답성이 중요한 장치들은 항상 Latency 확인이 필요하다

    • 단가, 수량, 성능 ← 성능 분석 결과 표 등

  • Firmware에서 시간 측정시 시작시간과 종료시간만 저장해두고 연산은 나중에 해야함

    • 로그 찍는것도 측정시간에 포함됨!!
  • 리눅스에서는 디바이스 드라이버가 장치에 전달하는 시간도 포함됨.

    • 정밀한 Latency 측정은 디바이스 드라이버에서 짜는게 더 정밀함

      • Driver Level에서 Latency 측정한다

어떤 라이브러리 사용?

  • 임베디드 소프트웨어는 보통 리눅스 환경에서 구동함

    ctime도 있찌만 timeval 구조체를 이용해 시간을 측정함

  • bit/time.h 헤더에 struct timeval가 정의되어있음

  • bit/time.h 헤더 파일은 sys/time.h헤더 파일에 선언되어있음

  • localtime 함수를 사용하면 사람이 보기 편한 정보로 확인 가능

  • us단위로 정밀한 현재 시간을 얻을 수 있음

예시

1
2
3
4
5
6
7
8
    struct timeval tv; 
    gettimeofday(&t, NULL); // timeval 객체에 알아서 넣어줌
    
    printf("%ld\\n", tv.tv_sec); // 1970.01.01 부터 지난 시간을 초로 계산해서 알려줌 
    printf("%ld\\n", tv.tv_usec); // 소수 6자리에 해당하는 숫자를 정수형으로 표현. 

    struct tm *p = localtime(t->tv_sec); // tm 구조체에 넣어줌 
    printf("%d %d", p->tm_sec, p->tm_usec);

정리

  1. 알고리즘에서는 ctime 헤더의 clock, time(NULL) 을 사용,
  2. 임베디드 환경에서는 bit/time.h 헤더에 struct timeval을 이용해서 시간을 측정
    • 초단위 : sleep 시스템 콜 사용
    • us 단위 시간측정 : clock 시스템 콜 사용
    • us 단위 현재 시간 측정 : gettimeofday
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.