TA (Matthew Allen)
will be the "director" of the warm-up project. All questions should be directed to him via email
or during his
office hours (Mon at 2-3 and Thu at 3-4).
Read this assignment in its entirety before beginning!
On this platform, you will measure several operating system features. In each experiment, you need to ensure that your measurements do not capture some anomalous behavior; therefore, to increase the confidence of your measurements, you should run each experiment multiple times within a loop and have your code report the average. While there are different ways you can determine the number of times your code must loop, the simplest is experimental. With this approach, you run each experiment manually, increasing the number of iterations each time, stopping when adding more iterations does not change the average.
The operating system and hardware provide various ways to measure time. In this first step, you need to identify two ways of measuring elapsed, real time (as opposed to accumulated process time) and determine the resolution (or precision) of the timer.
One way to determine the resolution of the timer is to read the clock value at the start and end of a simple loop. Start with a single loop iteration, then increase the iteration count of the loop until the difference between the before and after samples is greater than zero. Try to get the smallest non-zero positive difference. If a single iteration of a loop takes too much time, try putting simple statements between the two timer calls.
Repeat this test for each of the two ways that you measure elapsed time. Use the more precise way in the rest of your experiments.
Choose a simple kernel call such as getpid() and measure the elapsed time to perform the call. Choose two other kernel calls that you suspect perform trivial operations, and measure the time to perform these. Be careful that some versions of these simple kernel calls may cache their result in a variable on the first call, making subsequent calls artificially fast (if so, then report both results). Also be sure that the platform actually performs a system call.
Measure the time to context switch between two processes.
Choose one of the following two techniques for measuring this time:
- Use signals: Process A sends a signal to Process B. Upon receiving the signal, Process B sends a signal back to process A.
- Use a pipe: Process A sends a 1-word message to Process B. Upon receiving the message, Process B sends a 1-word message back to process A.
Measure the latency of a page fault for a zero-filled page (i.e., a page fault in which the OS both allocates a free page frame and fills it with zero values). One way to measure the zero-filled page fault processing latency is the following: use malloc() to allocate a large region of memory, then touch one word out of each page in the region, and measure how long the whole operation takes. As reasonable, present your results such that you separate the cost of malloc from the time to touch each page. Explore this cost as a function of the number of pages, ensuring that your region is large enough to produce measurable results, but still fits in RAM.
Measure the time to read from a large file using two different techniques:
- directly calling the UNIXread() system call
- map the file into memory usingmmap() and copy data from the mapped region into another buffer.
For both techniques, be sure to consider both files that are cached in RAM and on local disk. And, again, explore time as a function of the size of the read.