Write a parallel program pie.c in C or C++ (pie.cc) for Linux that computes an approximation of the number π using a series’ with N+1 terms. The series sum is partitioned in T non-overlapping partial sums, each computed by T separate child processes created with the fork() library function. This program demonstrates data parallelism and interprocess communication using pipes. Each child process could perform a (potentially) long computation on a separate CPU (or core), thus, the entire computation could reach a speedup close to T. Numbers N and T are passed from the shell to the pie program as command line parameters. The main(argc, argv[]) function call gets these parameters (T, N) in argv[1] and argv[2] as strings, respectively. (Element argv[0] contains the program name and we don’t need it.)

The first parameter, N, is the upper limit for i in the formula above. The second parameter, T, is the

number of child processes that compute partial sums. N should always be greater than T, N>T.

Otherwise the program should display an error message and call exit(1).

Use the Nilakantha approximation formula for π (http://en.wikipedia.org/wiki/Pi):

π = 3 + 4/(2*3*4) – 4/(4*5*6) + 4/(6*7*8) – 4/(8*9*10) + …. + k*4/((2*i)* (2*i+1)*( 2*i+2))+…

where k = 1 if i is odd and k = -1 if i is even and i goes from 1 to N.

The program can be run like this from the shell:

./pie N T

For instance,

./pie 100 4

This command computes the approximation with 101 terms (starting with term 3) with 4 child

processes.

Here is a description of the algorithm to be implemented.

The parent process iterates with an index variable of type int called j from 0 to T (0≤j<T). During

iteration with index j, the parent process …

1. creates a pipe associated with child process with index j

2. creates a child process with fork()

3. writes the values N, T, and j to the pipe

After ending the loop (above) that created the T child processes, the parent process starts a new loop,

with index j from 0 to T (0≤j<T). In iteration with index j, the parent process reads from the pipe

associated with child j the value of the partial sum computed by the child and adds it to an accumulator

double variable.

After the second loop ends, the parent process:

1. displays the sum approximating the value of π stored in the accumulator, with a message that

reads like:

2. The approximation of pi with N=%d and T=%d processes is %f.

(this is a C printf format string, make sure the code displays the actual numbers!)

3. waits for all child processes to end

4. exits with code 0.

The child process with index j runs its code in a function called computePartialSum.

In this function the child process does this:

1. closes any unnecessary file descriptors (which ones?)

2. reads values N,T, and j from the pipe, which were written by the parent process

3. computes the partial sum (as described below)

4. writes the partial sum to the pipe

5. calls exit(0).

NOTE: for this homework the child process should NOT rely on global variables to access N, T, and j.

These values must be read from the parent process using a pipe. Doing otherwise is considered a

mistake and points will be cut.

For example, if the user runs command

./pie 100 4

then :

child process #0 computes the partial sum for i going from 0 to 24

child process #1 computes the partial sum for i going from 25 to 49

child process #2 computes the partial sum for i going from 50 to 74

child process #3 computes the partial sum for i going from 75 to 99

## Expert Answer

#include <iostream> using namespace std; int main() { int counter = 1; double odd = 1; double sum = 0; int max = 10000; bool bSign = true; double pi = 0; //4-(4/3)+(4/5)-(4/7)+(4/9)-(4/11)+... do { if(bSign) { pi += 4 / odd; bSign = false; } else { pi -= 4 / odd; bSign = true; } odd+=2; counter++; sum += pi; cout << pi << endl; } while ( counter < max ); cout << "PI : " << (sum / counter) << endl; return 0; }