Welcome
» NERWous C
» Examples
Current Literature
One method to approximate Π (Pi) is to randomly generate a great number of points in a square with a circle inscribed in it. Count the number of points that fall inside the circle. Divide that number by the total number of randomly generated points. The value of Π is approximately 4 times the resulting quotient.
The more points generated, the better the approximation. To speed up the process, each generated point can be processed in parallel.
Sample serial code:
References:
NERWous C Sample
To run the above serial code in parallel with NERWous C, we need to make a few changes:
Each task increments the shared value
Previous Next Top
Current Literature
One method to approximate Π (Pi) is to randomly generate a great number of points in a square with a circle inscribed in it. Count the number of points that fall inside the circle. Divide that number by the total number of randomly generated points. The value of Π is approximately 4 times the resulting quotient.
The more points generated, the better the approximation. To speed up the process, each generated point can be processed in parallel.
Sample serial code:
void main()
{
double niter = 10000000;
double x,y,z,pi;
int i;
int count=0;
srand(time(NULL));
for (i=0; i<niter; ++i)
{
//get random points
x = (double)random()/RAND_MAX;
y = (double)random()/RAND_MAX;
z = sqrt((x*x)+(y*y)); //check if point is inside circle
if (z<=1) ++count;
}
pi = ((double)count/(double)niter)*4.0;
printf("Pi: %f\n", pi);
}
References:
- Lawrence Livermore National Laboratory -- Introduction to Parallel Computing
- Oak Ridge National Laboratory -- Serial to Parallel: Monte Carlo Operation
- Appentra Team -- A very simple simulation program: Parallel computation of PI
NERWous C Sample
To run the above serial code in parallel with NERWous C, we need to make a few changes:
void main()
{
double niter = 10000000;
<mel> int count=0;
srand(time(NULL));
for (int i=0; i<niter; ++i)
<! collect> {
double x, y, z;
//get random points
x = (double)random()/RAND_MAX;
y = (double)random()/RAND_MAX;
z = sqrt((x*x)+(y*y)); //check if point is inside circle
if (z<=1) <?>++count;
} <? ENDED>;
double pi = ((double)<?>count/(double)niter)*4.0;
printf("Pi: %f\n", pi);
}
The for
loop is still running serially, but each of its iterations creates a new task via the pel creation <!>
operation to run in parallel. Each independent task uses their own local variables x
, y
, z
to contain intermediate computations. If these variables were defined in the main
task instead, they would have to be imported into each of the tasks.
Each task increments the shared value
count
if it processes a point that falls inside the circle. Thus, the variable count
is now declared as a mel
variable. The for
loop is encased in a collect-ENDED block to allow the <? ENDED>
statement to ensure that all pelled tasks have ended. This allows the computation of the local variable pi
to work with a shared variable count
that has collected all the results from the pelled tasks.
Previous Next Top
No comments:
Post a Comment