(请原谅我的英语。) 你好。我正在开发一个.NET(C#)库,它为我的研究执行一些科学计算。有时我必须处理大量数据,因此我实现了并行循环来加速计算。但是我遇到了一个非常奇怪的错误:我有一段代码实现了Simson的方法(积分计算)。基本上,它只是一大笔钱。所以我使用Parallel.For方法得到这个总和(用"锁定"确保线程安全的代码片段。)
private static double Calculate3(Function<double, double> F, double a, double b, int n)
{
double h = (b - a) / n;
double val = 0.0;
object locker = new object();
Function<double, double> X = (x) => a + x * h;
Func<double> Init = () => 0d;
Func<int, ParallelLoopState, double, double> Work = (i, state, sum) =>
{
return sum + h * (F(X(i)) + F(X(i + 1)) + 4 * F((X(i) + X(i + 1)) / 2.0)) / 6.0;
};
Action<double> Finalize = (x) =>
{
lock (locker)
{
val += x;
}
};
Parallel.For<double>(0, n, Init, Work, Finalize);
return val;
}
当n不大时,此代码会生成正确的结果。如果n是约。 10000,我明白了:
4.0000000000026400 4.0000000000028700
4.0000000000028600 4.0000000000028700
4.0000000000016900 4.0000000000028700
4.0000000000026500 4.0000000000028700
3.9999999999970300 4.0000000000028700
4.0000000000019100 4.0000000000028700
让我们说,右列是我期望获得的精确值。它是通过建筑标准计算的。左列是我并行得到的。行表示此方法的顺序执行。 这个问题跟随我在每个我希望并行找到和的地方。 如果有人对这个问题有任何想法,我会很高兴听到,因为我觉得有一个错误,但我确实看到了它。