Time

 

  • Wall time (real time)
    • Actual time and data in the real world
    • Used when interfacing with the user or timestamping an event
      • Ideal for measuring absolute time
      • E.g., Noon on 1 March 1919
    • 실제 세상의 시간정보입니다
  • Monotonic time
    • This time source is strictly linearly increasing
    • 이 시간은 Wall time과 달리, 선형적으로 증가하는 시간입니다 
      • System's uptime (time since boot)
    • Deterministic and unchangeable
    • 이 시간은 Wall time과 달리, 바뀔 수 없고, 결정적인 시간입니다 
      • The wall time can change, because the user may set it, and because the system continually adjusts the time for skew
    • Useful for calculation the difference in the between two samplings
      • Suited for calculationg relative time
      • e.g., 5 seconds from now, or 10 minutes ago
  • Process time
    • Time that a process has consumed, either directly in user-space code, or indirectly via the kernel working on the process' behalf
    • CPU자원을 소비하는 process의 CPU자원을 소비했던 시간입니다
    • Mostly for profiling and statistics
    • The process time can be much less than the wall time for a given operation due to multitasking nature
    • CPU자원을 소비한 시간은 멀티 태스킹 환경에서는 context switch때문에 Wall time보다 작을 수 있습니다

 

Hardware Clocks

 

  • Real Time Clock (RTC)
    • Usually has battery backup power so that it tracks the time even while the computer is turned off
    • 부가적인 전원이 있어서 컴퓨터가 꺼져도 계속 시간을 추적할 수 있습니다
  • High Precision Event Timer (HPET)
    • Can produce periodic interrupts at a much higher resolution than the RTC
    • kernel에 주기적인 system call을 쏘는 것을 도와주는 Hardware Clock입니다. 이는 RTC보다 더 정확한 시간정보를 제공해주지만, 추가적인 전원이 없어서, 컴퓨터가 꺼지면 종료되는 특징을 가집니다
  • Time Stamp Counter (TSC)
    • 64-bit register in x86 processors
    • Counts the number of cycles since reset
    • HPET보다 저 정확한 시간을 제공하지만, periodic interrupt를 발생시키진 않는다는 특징을 가집니다. reset이후 부터 cycle의 횟수를 측정합니다.

 

System Clock (Software Clock)

 

  • When a timer interval ends, the kernel increments the elapsed time by one unit, known as a tick or a jiffy
    • The counter of elapsed ticks is known as the jiffies counter
    • 일정 타이머 간격이 끝나면 tick이나 jiffy라고 불리는 한 유닛의 카운트를 늘립니다
  • On Linux, the frequency of the system timer is called HZ
    • 100 → 10ms period → jiffies counters = 3 → 30ms
    • 250 → 4ms period (default)
    • 1000 → 1ms period → system overheads 증가

 

System Time

 

  • Reports seconds (and microseconds) since Unix time (00:00:00 UTC on 1 January 1970, aka Epoch time)
  • Year 2038 problem (Y2K38)

 

Data Structure

 

  • timeval structure
struct timeval{
    time_t tv_sec; /* second */
    suseconds_t tv_usec; /* microseconds */
};

 

 

Getting the current time

 

  • int gettimeofday(struct timeval *tv, struct timezone *tz)
  • Places the current time in the timeval structure pointed at by tv, and returns 0
  • Wall time (Real time)을 측정하는 것
  • The timezone structure and the tz parameter are obsolate (always pass NULL)
  • On failure, returns -1

 

Setting time

 

  • int settimeofday(const struct timeval *tv, const struct timezone *tz)
  • Sets the system time as given by tv and returns 0 (pass NULL for tz)
  • Wall time (Real time)을 새롭게 설정하는 것
  • On failure, returns -1

 

POSIX Clocks

 

  • CLOCK_REALTIME
    • The system-wide real time (wall time) clock
      • Setting this clock requires special privileges
  • CLOCK_MONOTONIC
    • A monotonically increasing clock that is not settable by any process
    • On Linux, the clock measures the time since system startup
  • CLOCK_PROCESS_CPUTIME_ID
    • A high-resolution, per-process clock available from the processor (i.e., TSC)
    • Measures the user and system CPU time consumed by the calling process
    • TSC와 같은 높은 정확도를 보이는 hardware clock을 사용하는 process의 CPU소비 시간을 측정하는 clock입니다
  • CLOCK_THREAD_CPUTIME_ID
    • Similar to the per-process clock, but unique to each thread in a process
    • thread의 CPU소비 시간을 측정하는 clock입니다.

 

Data Structure

 

  • timespec structure
struct timespec{
    time_t tv_sec; /* second */
    long tv_nsec; /* nanosecond */
};

 

Time source resolution

 

  • int clock_getres(clockid_t clock_id, struct timespec *res)
  • Stores the resolution of the clock specified by clock_id in res, if it is not NULL, and returns 0
  • On failure, returns -1

 

Example

 

clockid_t clocks[] = {
    CLOCK_REALTIME;
    CLOCK_MONOTONIC;
    CLOCK_PROCESS_CPUTIME_ID,
    CLOCK_THREAD_CPUTIME_ID,
    (clockid_t) -1
};
int i;

for(i=0; clocks[i] != (clockid_t) -1; i++){
    struct timespec res;
    int ret;
    
    ret = clock_getres(clocks[i], &res);
    if(ret)
        perror("clock_getres");
    else
        printf("clock=%d sec=%ld nsec=%ld\n",
        	clocks[i], res.tv_sec, res.tv_nsec);
}

 

result

 

Getting the current time

 

  • int clock_gettime(clockid_t clock_id, struct timespec *ts)
  • Stores the current time of the time source specified by clock_id in ts, and returns 0
  • On faiiure, returns -1
  • 만약, clock_id가 CLOCK_REALTIME이라면 gettimeofday()와 동일한 결과를 냅니다. 유일한 차이는 ms와 ns의 차이입니다

 

Setting time

 

  • int clock_settime(clockid_t clock_id, const struct timespec *ts)
  • The time source specified by clock_id is set to the time specified by ts, and returns 0
  • On failure, returns -1
  • 만약, clock_id가 CLOCK_MONOTONIC이라면 수정이 불가능합니다

 

Example

 

#define BILLION 1000000000L

unit64_t diff;
struct timespec start, end;
int i;

/* mesure monotonic time */
clock_gettime(CLOCK_MONOTONIC, &start); /* mark start time */
...                                     /* do stuff */
clock_gettime(CLOCK_MONOTONIC, &end);   /* mark the end time */

diff = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec;
printf("elapsed time = %llu nanoseconds\n", (long long unsigned int) diff);