Not able to get scaled performance on increasing number of threads
Sparsh Mittal
sparsh0mittal at gmail.com
Fri Feb 1 08:08:47 PST 2013
Here is the code:
#!/usr/bin/env rdmd
import std.stdio;
import std.concurrency;
import core.thread;
import std.datetime;
import std.conv;
import core.sync.barrier;
immutable int gridSize = 256;
immutable int MAXSTEPS = 50000; /* Maximum number of
iterations */
immutable double TOL_VAL =0.00001; /* Numerical Tolerance
*/
immutable double omega = 0.376;
immutable double one_minus_omega = 1.0 - 0.376;
immutable int numberOfThreads = 2;
double MAX_FUNC(double a, double b)
{
return a> b? a: b;
}
double ABS_VAL(double a)
{
return a> 0? a: -a;
}
__gshared Barrier myLocalBarrier = null;
shared double[gridSize+2][gridSize+2] gridInfo;
shared double maxError = 0.0;
void main(string args[])
{
for(int i=0; i<gridSize+2; i++)
{
for(int j=0; j<gridSize+2; j++)
{
if(i==0)
gridInfo[i][j] = 1.0;
else
gridInfo[i][j] = 0.0;
}
}
bool shouldCheck = false;
bool isConverged = false;
for(int iter = 1; iter <= MAXSTEPS; iter++)
{
shouldCheck = false;
if(iter % 400 ==0)
{
shouldCheck = true;
maxError = 0.0;
}
//This is Phase 1
{
myLocalBarrier = new Barrier(numberOfThreads+1);
for (int cc=0; cc<numberOfThreads; cc++)
{
spawn(&SolverSlave, thisTid,cc, 0 ,shouldCheck);
}
myLocalBarrier.wait();
}
//This is Phase 2
{
myLocalBarrier = new Barrier(numberOfThreads+1);
for (int cc=0; cc<numberOfThreads; cc++)
{
spawn(&SolverSlave, thisTid,cc, 1 ,shouldCheck );
}
myLocalBarrier.wait();
}
if( maxError < TOL_VAL)
{
isConverged = true;
break;
}
}
if(isConverged)
writeln("It converged");
else
writeln("It did not converge");
}
void SolverSlave(Tid owner, int myNumber, int remainder, bool
shouldCheckHere)
{
double sum =0;
//Divide task among threads
int iStart = ((myNumber*gridSize)/numberOfThreads) + 1;
int iEnd = (((myNumber+1)*gridSize)/numberOfThreads) ;
for(int i=iStart; i<= iEnd; i++)
{
for(int j=1; j< gridSize+1; j++)
{
if( ((i+j)%2 ==remainder)) //Phase 1 or 2
{
sum = ( gridInfo[i ][j+1] + gridInfo[i+1][j ] +
gridInfo[i-1][j ] + gridInfo[i ][j-1] )*0.25;
//Should not check everytime to reduce synchronization
overhead
if(shouldCheckHere)
{
maxError = MAX_FUNC(ABS_VAL(omega
*(sum-gridInfo[i][j])), maxError);
}
gridInfo[i][j] = one_minus_omega*gridInfo[i][j] +
omega*sum;
}
}
}
myLocalBarrier.wait();
}
More information about the Digitalmars-d-learn
mailing list