210202[ft_philosopher]gettimeofday

Modyhoon·2021년 2월 2일
1

Gettimeofday를 사용하면 현재 시간을 알 수 있다.

작동구조

1970-01-01 00:00:00 +0000(UTC) 이후의 현재까지 경과된 초와 micro초의 값을 얻는 함수이다.

함수 원형은 다음과 같다.

int gettimeofday(struct timeval *restrict tp, void *restrict tzp);
  • tp란 timeval 구조체로, 구조체 변수에 tv_sec, tv_usec이 있다.
  • 첫 번째 인자 tp는 timeval struct를 pointer형식으로 넣어주는 것으로, tp의 원본을 수정하기 위해 pointer값으로 넘겨준다.
  • 만약 pointer(주소)로 넘겨주지 않으면, 그저 구조체가 복사되어 전달되기 때문에 의미가 없어진다.
  • 두 번째 인자인 tzp는 timezone으로 시간대를 알려주는데, 현재는 사용되지 않고 NULL로 넣어주면 된다.

용도

이 함수를 이용해 서로 다른 두 시점에서 시간이 얼마나 경과했는지 조사할 수 있다.

예를 들어, 어떤 한 함수의 실행 시간을 알고자 한다면

struct timeval tv;
struct timeval tv2;

gettimeofday(&tv, NULL);
my_function();
gettimeofday(&tv2, NULL);

이런식으로 gettimeofday를 함수 시작 전, 후로 각각 넣어준다.
그 후 출력을 하고싶다면 나중에 부른 시간이 더 크므로
(tv2.tv_sec - tv.tv_sec) + (tv2.tv_usec - tv.tv_usec)
을 해주면 정확한 시간 값을 알 수 있다.

하지만 두 시간은 단위가 다르다.

tv_sec은 초이고, tv_usec은 마이크로 초(1 / 1000000초)이다.

따라서, 단위를 맞추어 주어야 한다. 컴퓨터는 단순 숫자만 저장할 뿐, 단위를 맞추어 주진 않는다.

그렇다면, 원본 시간초는 유지하면서도, 단위를 맞추는 방법은 뭐가 있을까?

tv_sec * 1000000 + tv_usec 

을 하면 초와 마이크로초 둘다 손실되지 않고 온전히 저장할 수 있다.

하지만 이렇게 된다면 굉장히 큰 자료형에 이 값을 집어 넣어야 한다.

시간 체크가 목적이라면, 우리는 두 시간 사이의 격차가 필요한 것이지 정확히 몇시 몇분 몇초에 코드가 실행 되었는지는 알 필요 없다.

따라서, 큰 단위의 자릿수는 쓸모없기 때문에 버린다.

tv_sec % 10000 * 1000000 + tv_usec

// tv_sec을 10000으로 나눈 나머지
// 즉, 만약 tv_sec이 123456789 라면,
// tv_sec % 10000은 6789이다.
// 따라서 6789를 usec단위로 맞추어 주기 위해
// 1000000을 곱하고, 그 뒤에 usec을 더해준다.

(추가) 헌데, 굳이 시간 interval을 계산하는거라면, int형에 집어넣어버리면 자동으로 overflow되기 때문에 크게 신경쓰지 않아도 될듯?

여러 시간을 비교하는거라면 overflow되는 횟수가 달라질 수 있기 때문에 비추.

과제

(ft_philosopher)

만약 두 시간을 잴 때, gettimeofday()함수로 시간을 구하면

tv_sec 과 tv_usec을 가져올 수 있다.

시작 시간을 배열에 저장해 둔다. (old[0], old[1])

그리고 현재 시간을 배열에 저장해 둔다. (cur[0], cur[1])

그 후, 시간을 계산하는 함수로 두 시간의 격차를 계산한다.

((cur[0] - old[0]) * 1000 + (cur[1] - old[1]) / 1000)

tv_sec에 1000을 곱하고, tv_usec에 1000을 나누는 이유는

단위를 ms(밀리 세컨드)로 맞추기 위함인데,

만약 tv_sec이 123456789 라면

1000을 곱해서

123456789000 으로 만들어 주고,

그 뒤에 usec을 1000으로 나누어 주면 ms가 되기 때문에 (만약 234829 라면, 234ms 829µs가 된다.)

따라서 12346789234 라는 값을 얻을 수 있다.

philosopher에서는 µs를 구하는 게 아닌 ms를 구하는 것이기 때문이다.

그런데 이러한 연산을 시간을 구하는 함수 안에 넣어두면 소요시간이 조금 걸리나보다. (지연이 생김)

따라서, 시간을 애초에 측정할 때, 연산을 미리 해줘서 return한 후 저장하고, 후에 연산하는 방식을 사용하니
해결되었다고 하신다.

profile
어제보다 나은 오늘

0개의 댓글