[C/C++] 수행 시간 측정 방법 (clock_gettime() 함수)

실험환경

  • OS: Ubuntu 18.04

코드를 작성하고 정확한 동작 시간을 확인해야 하는 경우가 있다. 이러면 clock() 함수를 사용해서 시간을 측정해도 되지만 Multi-Threads 프로그램을 사용하는 경우 잘못된 결과가 출력되는 경우가 발생한다. 이런 경우 clock_gettime(…) 함수를 사용해서 수행 시간을 측정하면 된다.

아래 코드 1은 clock_gettime(…) 함수를 사용해서 시간을 측정하는 예제 코드이다.

코드 1: 실행 시간을 측정하기 위한 코드

#include <stdio.h>
#include <time.h>

#define MAX 1000000

int main(){

    //MK: 시작/끝 시간을 측정하기 위해서 추가함 (time.h 필요)
    struct timespec  begin, end;
    double tmpValue = 0.0;

    //MK: 연산 시작과 함께 시간을 측정함
    clock_gettime(CLOCK_MONOTONIC, &begin);
    for(int i = 0; i < MAX; i++){
        tmpValue += i;
    }

    //MK: 연산이 끝나면 시간을 측정함
    clock_gettime(CLOCK_MONOTONIC, &end);
    printf("Value: %lf\n", tmpValue);

    //MK: 측정한 시간을 Nano, Micro, Milli, Second 단위로 출력함
    long time = (end.tv_sec - begin.tv_sec) + (end.tv_nsec - begin.tv_nsec);
    printf("Time (Nano): %ld\n", time);
    printf("Time (Micro): %lf\n", (double)time/1000);
    printf("Time (Milli): %lf\n", (double)time/1000000);
    printf("Time (Second): %lf\n", (double)time/1000000000);

    return 0;
    
}

코드가 단순해서 대부분 바로 이해할 수 있다고 판단된다. Struct timespec은 아래와 같이 2개의 변수를 가지고 있다. 한 개는 Second 단위를 기록하고, 다른 하나는 Nanoseconds 단위를 기록한다.

struct timespec {
        time_t   tv_sec;        /* seconds */
        long     tv_nsec;       /* nanoseconds */
};

clock_gettime(…) 함수에서 CLOCK_MONOTONIC을 사용하였다. CLOCK_MONOTONIC, CLOCK_REALTIME 인자를 사용할 수 있다. CLOCK_REALTIME을 사용해도 큰 문제는 없지만, 시스템 시간이 변경되는 경우 잘못된 결과를 출력할 수 있다고 한다.

위 코드 1을 컴파일해서 실행하면 아래와 같이 시간이 출력된다. 그림 제일 아래에 있는 결과는 리눅스 time 명령어를 사용해서 측정한 결과이다.

그림 1: 코드 1 실행 결과 화면

출처

  1. https://hand-over.tistory.com/74
  2. https://namneul.tistory.com/10

4 thoughts on “[C/C++] 수행 시간 측정 방법 (clock_gettime() 함수)”

  1. 당신의 소스는 치명적인 버그가 있습니다.
    아래의 부분이 잘못이 되었습니다. tv_sec과 tv_nsec은 수치가 다른데…같은 것으로 계산되어 있죠.
    long time = (end.tv_sec – begin.tv_sec) + (end.tv_nsec – begin.tv_nsec);
    다음과 같이 해야 할 것입니다.
    (https://exeter.tistory.com/86 를 참조)
    long time = 1000000000 * (end.tv_sec – begin.tv_sec) + (end.tv_nsec – begin.tv_nsec);
    님의 소스는 짧게 수행되기 때문에 start와 end의 tv_sec이 같아서…tv_nsec의 차이로만 측정되어
    잘 수행되는 것처럼 보이지만…tv_sec이 소요되는 긴 시간 check시에는 잘못된 값이 보일 것입니다.
    수고하세요.

    Reply
  2. 코드의 중반 부분에서 long time = (end.tv_sec – begin.tv_sec) + (end.tv_nsec – begin.tv_nsec);
    이 코드가 이해되지 않아서 댓글 남기게 되었습니다.
    nsec를 서로 빼는 것만으로도 시간을 충분히 구할 수 있는데 sec의 시간을 한번 더 더하는 점이 이해가 되지 않아서 질문드립니다 !

    Reply

Leave a Reply to 1 Cancel reply