我需要使用PLINQ - 库通过Monte-Carlo方法计算Pi数,但是当我的并行程序运行时,它计算的Pi数比它的不平行模拟长得多。如何解决?并行计算类及其不可比拟的模拟如下:
class CalcPiPLINQ
{
int n;
double aPi;
int counter;
public StringBuilder Msg; // diagnostic message
public void Init(int aN)
{
//stopWatch.Start();
n = aN; // save total calculate-iterations amount
aPi = -1; // flag, if no any calculate-iteration has been completed
Msg = new StringBuilder("No any calculate-iteration has been completed");
}
public void Run()
{
if (n < 1)
{
Msg = new StringBuilder("Invalid N-value");
return;
}
Random rnd = new Random(); // create random-numbers generator
Stopwatch stopWatch = Stopwatch.StartNew();
var numbers = ParallelEnumerable.Range(0, n);
var result = Enumerable
.Range(0, n)
.Select(i => new { X = rnd.NextDouble(), Y = rnd.NextDouble() })
.AsParallel()
.Select(p => Check(p.X, p.Y))
.Count(b => b);
aPi = 4.0 * ((double)result / (double)n); // calculate approximate Pi-value
//stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine("RunTime " + elapsedTime);
}
public double Done()
{
if (aPi > 0)
{
Msg = new StringBuilder("Calculations are completed successful!");
return aPi; // return calculated value
}
else
{
return 0; // no result
}
}
public bool Check(double x, double y)
{
return ((x - 0.5) * (x - 0.5) + (y - 0.5) * (y - 0.5)) < 0.25;
}
public void CheckWithCounter(double x, double y)
{
if(((x - 0.5) * (x - 0.5) + (y - 0.5) * (y - 0.5)) < 0.25)
{
Interlocked.Increment(ref counter);
}
}
}
不平行的模拟:
class TCalcPi//unparallel calculating method
{
int N;
int N_0;
double aPi;
public StringBuilder Msg; // diagnostic message
double x, y;
Stopwatch stopWatch = new Stopwatch();
public void Init(int aN)
{
stopWatch.Start();
N = aN; // save total calculate-iterations amount
aPi = -1; // flag, if no any calculate-iteration has been completed
Msg = new StringBuilder("No any calculate-iteration has been completed");
}
public void Run()
{
if (N < 1)
{
Msg = new StringBuilder("Invalid N - value");
return;
}
int i;
Random rnd = new Random(); // to create randomizer
for (i = 1; i <= N; i++)
{
x = rnd.NextDouble(); // to generate coordinates
y = rnd.NextDouble(); //
if (((x - 0.5) * (x - 0.5) + (y - 0.5) * (y - 0.5)) < 0.25)
{
N_0++; // coordinate in a circle! mark it by incrementing N_0
}
}
aPi = 4.0 * ((double)N_0 / (double)N); // to calculate approximate Pi - value
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine("RunTime " + elapsedTime);
}
public double Done()
{
if (aPi > 0)
{
Msg = new StringBuilder("Calculates has been completed successful");
return aPi; // return gotten value
}
else
{
return 0; // no result
}
}
}