5570: Advanced Unix Programming

Programming assignment 2

Objectives

Deadlines

Submission instructions

Background

The ability to execute multiple processes concurrently is very useful for scientific applications running on parallel or distributed environments. The application's task is broken into pieces, and each piece is assigned a process, which is responsible for completing it. The processes may run simultaneously on different processors, thereby speeding up the computation. Of course, the work done by each task may not be independent, and so they need to communicate with each other.

Monte Carlo computations are particularly efficient to run in such a parallel environment, since the communication requirements are low. In these computations, typically, each process carries out identical work, but uses a different random number sequence to get a different result. The results from all the processes are then finally combined, to yield the answer.

Description

You will write a program that estimates the value of pi. It will accept a command line argument P, which is the number of processes that will work together to estimate pi.

Details

We have provided a file, pi.c, which defines function double EstimatePi(long NumberOfSimulations, int ProcessRank). It uses the ProcessRank to create a unique random number sequence, and returns an estimate of pi using NumberOfSimulations simulations. The interface to pi.c is provided by the header file pi.h .

The larger the number of simulations, the more accurate the answer is. Instead of one process performing a large number of simulations, we can have multiple processes performing a smaller number of simulations "simultaneously". Of course, since we are not using a parallel machine, you will not actually observe a significant improvement in performance.

Your program will determine P from the command line argument, and will fork P-1 other processes (either directly or indirectly). This set of P processes will repeatedly estimate pi, using increasingly larger numbers of simulations, as described below, until the user decides to terminate the computation by sending a SIGINT to the parent process.

Each process should be assigned a unique processes rank in [0,P-1]. (You need to figure out a way to do this.) Each process will then set the number of simulations at 1000000 (one million), and then call EstimatePi(NumberOfSimulations, ProcessRank) to get its estimate of pi.

Pi is then estimated (over the entire set of processes) by averaging the estimates from each process. This is performed in two steps. First the value of pi from each process is added (which we call a reduction operaton), as described below.

The reduction operation requires communication between processes, and you should use pipes to perform this. A simple way of performing the reduction is to have each process send its value to the parent, and then have the parent add up the values. However, this will take O(P) time even on a parallel machine, and so is considered inefficient. A more efficient algorithm uses a tree structured computation, and takes O(log P) time. (Since we are not on a parallel machine, you will not notice an improvement in speed; however, you should use the latter algorithm. If you find it difficult, then you may use the simpler algorithm, but will lose a few points for that.) You can read about the efficient algorithm from page 38-39 (section 2.3.2) of Designing and Building Parallel Programs, by Ian Foster, available online at: http://www-unix.mcs.anl.gov/dbpp. Please make sure that you handle the case where the number of processes is not a power of two.

Next, the sum computed above is divided by the number of processes, to get the estimate. This estimate is output to stdout.

All the processes then double the value of the number of simulations (to 2000000) and repeat the above process. They keep repeating this process, doubling the number of simulations and then outputing the new estimate. (If doubling the number of simulations will cause the value to exceed LONG_MAX, then they will not double the number of simulations, but just repeat, with the same number of simulations.)

When the user is satisfied that pi is sufficiently accurate, the user will send a SIGINT to the parent. The parent will not terminate immediately. Instead, the next estimate of pi is computed and output, and then the parent causes all the children to terminate, and also terminates itself. Note that you may need to block SIGINT in a major portion of your computation, in order to accomplish this.

Grading criteria

Your assignment will be graded by the criteria given below

Files to download

http://www.cs.fsu.edu/~asriniva/courses/aup02/hws/hw2/pi.c and http://www.cs.fsu.edu/~asriniva/courses/aup02/hws/hw2/pi.h

Note

(i) Please use linprog or program for your programming needs. Please do not use the department's servers such as diablo, quake, of xi, since errors in your program can cause inconvenience to other users.

(ii) Please do not compile pi.c with -ansi -pedantic flags.

Examples:

(i) Compile http://www.cs.fsu.edu/~asriniva/courses/aup02/hws/hw2/usepi.c with pi.c. Running this program will show you the output for the first few iterations. Note that this program does not handle signals, does not use multiple processes, and its handling of N will not work for large N (since it will cause an overflow). Your code will be more complicated, and the logic for incrementing N will be a little different. (ii) The executable http://www.cs.fsu.edu/~asriniva/courses/aup02/hws/hw2/hw2 handles signals and the incrementation of N correctly (for normal situations), but I will not show you the source code! You can use it to determine how the program should behave (under normal circumstances).
Last modified: 24 Sep 2002