Parallel.For没有给出一致的结果[重复]

Posted

技术标签:

【中文标题】Parallel.For没有给出一致的结果[重复]【英文标题】:Parallel.For not giving consistent results [duplicate] 【发布时间】:2016-07-06 12:51:49 【问题描述】:

当我运行下面的代码时,第 5 位和第 6 位的结果总是不同的:

public void TestParallel()
    
        object locker = new object();
        double grandTotal = 0;
        Parallel.For( 1, 1000000,

            () => 0.0, // Initialize the local value.

            ( i, state, localTotal ) => // Body delegate. Notice that it
            
                return localTotal + Math.Sqrt( i ); // returns the new local total.
            ,

            localTotal => // Add the local value
            
                lock( locker ) grandTotal += localTotal; // to the master value.
            
            );
        Console.WriteLine( string.Format( "Grand Total = 0", grandTotal ) );
    

我不知道为什么结果并不总是总计 = 666666166,458842。这是我这样运行时得到的:

double grandTotal = 0;
for ( int i = 1; i < 1000000; i++ )

    grandTotal += Math.Sqrt( i ); // returns the new local total.

Console.WriteLine( string.Format( "Grand Total = 0", grandTotal ) );

【问题讨论】:

浮点数学很难。 您也可以使用多个线程更改单个变量。这些处理的顺序将会改变 @Liam 请注意,他更改的唯一共享变量是 grandTotal,他在更改之前将其锁定。 好点@Liam。 Sqrt 函数可能是现代处理器上的一条指令,虽然它可能有多个“虚拟处理器”,但它们可能没有多个浮点单元。在这种特殊情况下,Parallel.For 不太可能显示出任何好处(并且可能由于锁定而减慢速度)。 浮动加法不是关联的。进化顺序很重要。比较(-1000000 + 1000000) + 0.1-1000000 + (1000000 + 0.1) 【参考方案1】:

对于浮点计算,1.0 + 0.9 并不总是等于 0.9 + 1.0

【讨论】:

【参考方案2】:

您会得到不一致的结果,因为浮点运算会对数字进行四舍五入。而四舍五入取决于被四舍五入的数字。

因此 (0+1)+sqrt(2) 不能保证等于 (0+sqrt(2))+1。

【讨论】:

以上是关于Parallel.For没有给出一致的结果[重复]的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB(PyMongo)分页具有不同的不给出一致的结果

Android camera.action.CROP 没有给出一致的结果

现有的类似于 Parallel.For 的 LINQ 扩展方法? [复制]

字符串拆分方法没有给出预期的结果[重复]

Task

OpenMP:不能同时使用 omp parallel for 和 omp task 吗? /错误:工作共享区域可能没有紧密嵌套在工作共享内