CS 3733 Operating Systems, Fall 2010 Assignment 4


Due Friday, October 29, 2010


Overview
The last three assignments of the semester will explore the use of concurrency to solve a simple problem. This assignment will involve processes (created by forking). Assignment 5 will use POSIX threads, and Assignment 6 will use network communication. Part 1 of this project will be used in all three assignments, so it is important that you start this early and make sure that it is fully debugged.

Students in CS 3843 this semester wrote a program to determine the value that a bit pattern would represent in a given floating point format.
They wrote the following function:
double getValue(int expSize, int fracSize, unsigned long long bits);
In the special case in which expSize=8 and fracSize=23, the low order 32 bits should be the same as the standard IEEE single-precision floating point representation.

In this case we can test to see if getValue is correct by comparing its return value to the corresponding return value of

double singlePrecision(unsigned long long num) {
   float f;
   f = *((float *)(&num));
   return (double)f;
}
Testing for correctness of getValue in this case requires testing all 232 possible 32-bit values.
Your problem is to determine whether a given student solution is correct, and if not, for which values it fails.
You will be given an object file, getValue.o, containing the getValue function.
You will write a program that calls this getValue with all 4 billion possible inputs.

Part 1
Make a directory, assign4, for this assignment.
Get a copy of getValue here.
Write a main program, assign4-1.c, that takes two command line parameters, start and end.
The program should begin by printing your name and the two command line parameters.
It then calls getValue with the first two parameters 8 and 23 and compares the result to singlePrecision.
Do this in a loop for values of num from start to end.
Choose values so that the program runs for a few seconds.
Keep a count of the number of values for which they give the same result and the number of values for which they differ.
Output these two values after the loop terminates.
Note: These functions can return the value NaN. Two values that are NaN should always be considered the same for this assignment.

If you find a value of num for which the student's answer is incorrect, print a line giving the value of num (in hexadecimal) and the values returned by getValue and singlePrecision, which should be different.
Output these last two double values using the format specification "%.10g".

Compile your program using:
gcc -c assign4-1 assign4-1.c getValue.o

Note: your program should work for input values of start and end between 0 and 232 -1.
These will not necessarily fit in an int, but will fit in an unsigned int.
If start is greater than end your program should not test any values.

Implementation note: Your program should report the correct counts even if no errors are found and the range is as large as possible.
In this case the correct count will not fit in 32 bits.

Part 2
After the program in Part 1 has been debugged, estimate how long it would take to run the program for start = 0 and end = 232 - 1.
Run the program with these values when you have time to do this.
If you use one of the machines in the lab and write your program efficiently, it should complete in a few minutes.
If it takes longer than this, you are doing something wrong.
Come and see me with your source code and discuss it with me.

The copy of getValue you have been given should fail on about a dozen of the possible values.
It may give different results of run on different days, but multiple runs on the same day should give the same results.

Run your program using the time command:
time assign4-1 0 4294967295
Save the results by cutting and pasting the output into a file.
In that file, record the date and time the program was started, along with what machine it was run on.

Part 3
In this part you are going to speed up your program by having multiple processes work on it concurrently.
Make a new main program called assign4-3.c which is similar to the one in Part 1, but breaks the range in 4 almost equal parts.
It will fork three children.
Each child and the main program will handle about 1/4 of the values.
Have each process start by printing a line indicating its process ID and the range of values it is testing.
Have the original parent wait for all of its childern and print a message before it terminates.
For this part, each process will produce a separate count of the number of correct and incorrect results.
The 4 processes will be concurrently outputting to standard output, and it is possible (but unlikely) that the output will be interleaved.
You will handle this problem in Part 4.
Run the program as you did before using the time function and save the results along with the data and time your ran the program and which machine it was run on..

If all goes well, this version will run about 4 times as fast and the one in Part 2 if you run on a computer with at least 4 cores.
Most of the machines in the lab have 4 cores, but the remote machines, mainxx only have 2 cores.

Try to run your program for Part 3 on the same type of machine as for Part 2, and calculate the speedup:
speedup = time for Part 2 divided by time for part 3.

Part 4
Make a new main program called assign4-4.c which is similar to the one in Part 3, but it will handle two problems:

  1. The output from different processes cannot be interleaved.
  2. The success and failure counts will be combined, so that we get one count for the successes and one for the failures.
You can solve this problem in any way you know how, but you need to retain the concurrency of Part 3.
Your solution to Part 4 should not run significantly slower than the one for Part 3.
Write a paragraph that describes how you solved these two problems and why your solution is correct.

Handing in the assignment
Use this cover sheet for handing in your assignment. Answer the questions listed on the cover sheet.