0

(请原谅我的英语。)你好。我正在开发一个 .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

假设,右列是我期望得到的精确值。它是通过施工标准计算的。左栏是我并行得到的。行表示此方法的顺序执行。这个问题在我想并行查找总和的每个地方都伴随着我。如果有人对这个问题有任何想法,我会很高兴听到,因为我觉得有一个错误,但我确实没有看到。

4

0 回答 0