Time and Timers Portions of these overheads taken from: Unix Systems Programming Communication, Concurrency, and Threads , by Robbins and Robbins
Why Time? What time is it? Arrange for event execution at (after) time t? Which portion of code should be optimized? How can I get make to operate correctly when I work from multiple machines?
Overview “Absolute” time 1. Measurement and error 2. Measuring program execution time 3. Scheduling event execution 4.
Absolute time: POSIX Times POSIX specifies systems should keep time in seconds since the Epoch Each day is 86,400 seconds Epoch: 00:00 (midnight) January 1, 1970 Extensions address higher resolutions
#include <time.h> time_t time(time_t *T); On success, returns seconds since Epoch; -1 otherwise If T not null, also stored in T #include <time.h> double difftime(time_t time1, time_t time0); Returns number of seconds elapsed between time0 and time1 , represented as a double. time1, time0 are seconds since Epoch.
Absolute time: Linux Hardware Clock Runs independently of any control program running on CPU Battery powered; runs even while system powered down hwclock(8) to query/set System Time Seconds since epoch Kept via clock in Linux kernel Software counter based on timer interrupt Initialized using hardware clock on boot date(1) to query/set
Absolute Time Clocks drift over time C i (t) denotes value of systems i’s clock at time t Drift rate – relative amount clock rate differs from perfect clock (C i (t 1 )-C i (t 2 )) / (t 1 -t 2 ) |C i (t)-C j (t)| is clock skew Skew commonly unbounded
Absolute Time Network Time Protocol (NTP) Protocol to synchronize local clock to external reference Time server, radio clock, GPS receiver Clocks synchronized to each other via mutual synchronization to reference Avoids discontinuities in clock values GPS hardware Allows tight synchronization (nanoseconds) to UTC No network connectivity required Need antenna
Format Conversion char *asctime(const struct tm *timeptr) char *ctime(const time_t *clock) struct tm *gmtime(const time_t *timer) struct tm *localtime(const time_t *timer)
Measurement and Error Impact of clock resolution Available resolution
Impact of Clock Resolution Clock Value Time
Measurement Error Single interval measurement Off by +/- resolution interval ε Multiple interval measurements No limit; +/- ε with each measurement for (i=0;i<MAX;i++){ measure execution time for interval add to total } Total : ε + ε/2 + ε − ε/3 + ε + ε + ε … Over/under estimates will tend to balance out over large number of measurements
Increasing the resolution #include <sys/time.h> int gettimeofday(struct timeval *tp, void *tzp); struct timeval{ time_t tv_sec; /* seconds since Epoch */ time_t tv_usec; /* and microseconds */ } Returns zero; tzp must be NULL; tp holds retrieved time Check your system, some do not have microsecond resolution
#define MILLION 1000000L int main(void) { long timedif; struct timeval tpend, tpstart; if (gettimeofday(&tpstart, NULL)) { fprintf(stderr, "Failed to get start time\n"); return 1; } // function_to_time(); sleep(1); if (gettimeofday(&tpend, NULL)) { fprintf(stderr, "Failed to get end time\n"); return 1; } timedif = MILLION*(tpend.tv_sec - tpstart.tv_sec) + tpend.tv_usec - tpstart.tv_usec; printf("The function_to_time took %ld microseconds\n", timedif); return 0; }
[jmayo@asimov ~/codeExamples]$ ./gettimeofdaytiming The function_to_time took 1002038 microseconds [jmayo@asimov ~/codeExamples]$ ./gettimeofdaytiming The function_to_time took 1002047 microseconds [jmayo@asimov ~/codeExamples]$ ./gettimeofdaytiming The function_to_time took 1002046 microseconds
Pentium RDTSC Read Time Stamp Counter (RDTSC) Instruction Returns clock cycles since power up or reset #seconds = #cycles/frequency Two byte instruction: 0F 31 Returns a 64-bit count in EDX:EAX 2^32 cycles/(2,000,000,000HZ)=2.1475 sec 2^64 cycles/(2,000,000,000HZ)=9223372035 sec 153722867.3 min 292.4712 years
rdtsc ; read time stamp mov time, eax ; move ctr into variable fdiv ; floating point divide rdtsc ; read time stamp sub eax, time ; find the difference cpuid ; prior inst must finish rdtsc ; read time stamp mov time, eax ; move ctr into variable fdiv ; floating point divide cpuid ; rdtsc ; read time stamp sub eax, time ; find the difference
/* Typedef for a 64-bit wide unsigned int */ typedef struct { unsigned long low; unsigned long high; } UINT64; /* Read Timer Stamp Counter */ UINT64 rdtsc(void) { UINT64 x; __asm__ volatile(".byte 0x0f,0x31" : "=a" (x.low), "=d" (x.high)); return x; } /* Read Timer Stamp Counter */ unsigned long long int rdtsc(void) { unsigned long long int x; __asm__ volatile(".byte 0x0f,0x31" : "=A" (x)); return x; }
/* Read Timer Stamp Counter */ unsigned long long int rdtsc(void) { unsigned long long int x; __asm__ volatile(".byte 0x0f,0x31" : "=A" (x)); return x; } main(){ unsigned long long llstart,llend; llstart=rdtsc(); /*They say you must do this*/ llstart=rdtsc(); llstart=rdtsc(); sleep(1); llend=rdtsc(); printf("Long long <%llu>\n",llend-llstart); }
asimov% ./rdtsc Long long <2605195700> asimov% ./rdtsc Long long <2604964942> asimov% cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 15 model : 2 model name : Intel(R) Pentium(R) 4 CPU 2.60GHz stepping : 9 cpu MHz : 2593.704 cache size : 512 KB physical id : 0 siblings : 2 fdiv_bug : no …
fortran% ./rdtsc Long long <3010263870> jmayo% ./rdtsc Long long <3012787470> jmayo% cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 15 model : 3 model name : Intel(R) Pentium(R) 4 CPU 3.00GHz stepping : 3 cpu MHz : 2992.782 cache size : 1024 KB physical id : 0 siblings : 2 fdiv_bug : no …
Measuring Program Execution Times Impact of multiprocessing Measurement interface
CPU and Wall Clock Time Wall Clock Time Wall Clock Time P1 P1 P1 P1 P1 P1 OS on behalf of P1 Idle OS on behalf of P1 Idle
CPU and Wall clock time Total CPU Time (wall clock time) Process time: executing instructions in any user process 1. System time: execution operating system instructions 2. Idle time: no process running 3. Process CPU time User time: executing instructions in particular user 1. process + System time: operating system executing on behalf of 2. particular process Wall clock time is system time + user time + idle time Include time process is not execution TSC measures wall clock time
Measuring Process Execution Time #include <sys/time.h> int times(struct tms *buffer); struct tms{ clock_t tms_utime; /* user CPU time of process*/ clock_t tms_stime; /* system CPU time of process */ clock_t tms_cutime; /* utime for process & term. children */ clock_t tms_cstime; /* stime for process & term. children */ }
The tms__utime field contains the CPU time spent executing instructions of the calling process. The tms__stime field contains the CPU time spent in the system while executing tasks on behalf of the calling process. The tms__cutime field contains the sum of the tms__utime and tms__cutime values for all waited-for terminated children. The tms__cstime field contains the sum of the tms__stime and tms__cstime values for all waited-for terminated children. Times for terminated children (and their descendants) is added in at the moment wait(2) or waitpid(2) returns their process ID. In particular, times of grandchildren that the children did not wait for are never seen.
All times reported are in clock ticks. The function times returns the number of clock ticks that have Elapsed since an arbitrary point in the past. For Linux this point is the moment the system was booted. This return value may overflow the possible range of type clock_t. On error, (clock_t) -1 is returned, and errno is set appropriately. The number of clock ticks per second can be obtained using sysconf(_SC_CLK_TCK); In POSIX-1996 the symbol CLK_TCK (defined in_<time.h>) is mentioned as obsolescent. It is obsolete now. On Linux, if the disposition of SIGCHLD is set to SIG__IGN then the times of terminated children are automatically included in the tms__cstime and tms__cutime fields, although POSIX 1003.1-2001 says that this should only happen if the calling process wait()s on its children.
#include <unistd.h> main(){ long ticks; ticks=sysconf(_SC_CLK_TCK); printf("<%ld>\n", ticks); } jmayo@asimov% getTicks <100>
Recommend
More recommend