(请原谅我的英语。)你好。我正在开发一个 .NET(C#) 库,为我的研究执行一些科学计算。有时我必须处理大量数据,所以我实现了并行循环来加速计算。但是我遇到了一个很奇怪的错误:我有一段代码实现了 Simson 的方法(Integral Calculations)。基本上,这只是一笔巨款。所以我使用 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
假设,右列是我期望得到的精确值。它是通过施工标准计算的。左栏是我并行得到的。行表示此方法的顺序执行。这个问题在我想并行查找总和的每个地方都伴随着我。如果有人对这个问题有任何想法,我会很高兴听到,因为我觉得有一个错误,但我确实没有看到。