4061 Session 17 (3/19). Today Time in UNIX Today’s Objectives Define what is meant when a system...

23
4061 Session 17 (3/19)

Transcript of 4061 Session 17 (3/19). Today Time in UNIX Today’s Objectives Define what is meant when a system...

4061 Session 17 (3/19)

Today

• Time in UNIX

Today’s Objectives• Define what is meant when a system is

called “interrupt-driven”

• Describe some trade-offs in setting the timer interrupt frequency

• Write programs that format time values, measure time intervals, and utilize high-precision or interval timers

Admin

• Remember - Homework 3 is due a week from Wed.

• Quiz 3 Results, overview, questions– Grading questions: Qiang #2/4, Riea #1/3

Frequency

0

5

10

15

20

25

30

35

40

45

F D C B A More

Frequency

Time in Perspective

• 1 second (s) ==1,000 milliseconds (ms) ==1,000,000 microseconds (μs)

• Million Instructions Per Second (MIPS)– A measure of *peak* CPU speed (not comparable

across architectures...)– 1992: Intel 486DX (66 MHz) - 54 MIPS– 2006: Intel Core 2 Extreme QX6700 (3.33 GHz) -

57063 MIPS

• Thus, 57,063,000,000 instructions per second, or 57,063 instructions per microsecond

Interrupt-Driven

• Systems have a “heartbeat”– Every so often, a timer interrupts whatever is

happening, and the OS determines what to do next (e.g. scheduling)

• The period between beats is known as a “jiffy”– Increment a kernel-internal value (jiffies) every timer

interrupt.• The timer interrupt is the default scheduling

quantum– All other timers are based on jiffies.– The timer interrupt rate (and jiffy increment rate) is

defined by a compile-time constant called HZ

Tuning

• Older linux kernels on Intel: 10 ms (1/100 s, 100 Hz)– 10 ms == 10,000 μs– up to 570,630,000 instructions per jiffy on

really fast HW

• Newer linux kernels on Intel: 4 ms (1/250 s, 250 Hz)

• For a few revisions, kernels were set to 1 ms. Deemed too short. Why?

Timer Interrupt Frequency

• Higher frequency leads to:– (+) better latency– (+) more timer granularity– (+) better performance for poll()/select()– (-) overhead (lower throughput)

• “jiffie wraparound” bug: system uptime clock– 32 bits, 100 jiffies per second = 497 days– (they fixed by moving to 64 bit storage)

Notes

• Note: timeslice != jiffy– Scheduling is implemented by checking

against the jiffy counter, but the length of a quantum can be longer than one jiffy

• vmstat 1: look at interrupts per second– On an idle system, can get a feel for timer Hz– in: interrupts in last second– cs: context switches in last second

Timers and Jiffies

• We’re going to be talking about timers today– e.g. How sleep(10) is implemented

• Keep in mind that without special kernel modifications timers can be no more accurate than the length of the jiffy– These special kernel modifications are written,

and will likely be put in the linux mainline code soon

Time and Timers

• An alarm is a signal that is delivered to a process after a time interval.

• The resolution of a clock is the minimum interval that can be represented.

• The accuracy of a clock is its difference from some generally-accepted standard.

• Time interval measurements are available for– wall-clock time,– user-mode runtime,– kernel-mode runtime, and– user-mode and kernel-mode runtime for children

Getting the Time

• From the command line with date, in a variety of formats, in any timezone.

• time_t time(time_t *tm)– This gives you the "time since epoch" in

seconds.– Returns and (optionally) stores result in tm.

• Accurate computation of long time intervals is not possible, because Unix time ignores leap seconds.

Y2K, Unix-style

• time_t datatype used to store seconds since Jan 1, 1970

• time_t was originally a 32 bit signed long• This number wraps (the highest-order bit is set

to 1) during the year 2038, indicating a time *before* 1970

• ...this is only a problem for 32 bit systems (changing these systems to use 64 bit longs is hard)– Will there be any 32 bit systems left in 2038?

From Wikipedia

• Using a (signed) 64-bit value introduces a new wraparound date in about 290 billion years, on Sunday, December 4, 292,277,026,596.

• The 128-bit Unix time resets later, on December 31, 17,014,118,346,046,923,173,168,730,371,588,410.

• However, these are not widely regarded as pressing issues.

Higher-precision Times

int gettimeofday(struct timeval *tv, struct timezone *tz);

struct timeval {

time_t tv_sec; /* seconds */

suseconds_t tv_usec; /* microseconds */

};

• This gives you the time with microsecond resolution, but not microsecond accuracy.

• The tz value is ignored. Just use NULL.

NTP

• Many network algorithms require (reasonably) accurate comparison of times across a network.

• How do I know that both machines are set correctly?

• Network-connected machines can achieve millisecond accuracy with the network time protocol NTP.

Time Formatting

• Given a time value, there are two steps to getting a human-readable string representing the time.– Break the time down into parts: seconds, minutes, hours, month,

year. See man ctime.– Convert the broken-down time into a string.– Set time zone info in tzname, timezone.

• Many of these functions use static data.– If you call ctime() or gmtime() a second time, the results from

the first call may be gone.– There are "thread-safe" versions of these, eg. ctime_r() , but

they still use static locations for timezone info.

Sleep and Alarm

• The alarm(m) call causes SIGALRM to be sent to your process after m seconds. The sleep(m) call uses SIGALRM to pause your process.

• A higher-precision way to get your process to pause:– int nanosleep(const struct timespec *req, struct timespec *rem);

• req is the desired pause time.• If interrupted, rem is the remaining unused time.

Process Pauses

• nanosleep() has different behaviors– Delay <= 2 ms: busy loop (no signals!)– Delay > 2 ms: implemented like sleep()

• The BSD version is called usleep(usec)– This is considered obsolete in Linux.– From the standpoint of simplicity, portability,

and efficiency, nanosleep() is almost always the best choice.

Interval Timers

• Each process has a set of interval timers available. You can set them to send a periodic signal, based on passage of real time, or runtime.

• Use getitimer(...) and setitimer(...)

Interval Timers (2)

• The three interval timers:– ITIMER_REAL

• decrements in real time• delivers SIGALRM

– ITIMER_VIRTUAL• decrements only when the process is executing• delivers SIGVTALRM

– ITIMER_PROF• decrements both when the process executes and when the

system is executing on behalf of the process. • delivers SIGPROF

• Each has a current value, and an “interval”• If the interval > 0, then the timer will restart

Measuring Runtime

• The system keeps track of time spent in user and kernel, for a process and its children.– clock_t times(struct tms *buffer);

• Returns accumulated runtime.