对于阶乘(并行和正常),答案是不相同的

jac*_*sha 3 c# parallel-processing task-parallel-library

以下为什么不是相同的答案?

正常编码:

long sum = 0;

for (long i = 1; i <= 10; i++)
{
    long result = 1;

    for (long j = 1; j <= i; j++)
    {
        result = result*j;
    }
    sum = sum + result;
}
Run Code Online (Sandbox Code Playgroud)

并行编码:

long sum = 0;

Parallel.For(1, 10, delegate(int i)
    {
        long result = 1;

        Parallel.For(1, i, delegate(int j)
            {
                result = result*j;
            });

        sum = sum + result;
    });
Run Code Online (Sandbox Code Playgroud)

请告诉我正确的方法

for (long i = 1; i <= 5; i++)
        {
            sum = sum * i;
        }
Run Code Online (Sandbox Code Playgroud)

Parallel.For(1, 5, delegate(int i)
    {
        sum = sum * i;
    });
Run Code Online (Sandbox Code Playgroud)

并行结果= 24

正常结果= 120

pad*_*pad 5

并行版本的答案是任意的,因为sum并且result由不同的线程访问和修改.所以你应该做的是分开计算每一步和总结结果.为了能够正确地总结结果,您需要获取一个锁,以便线程sum专门修改.一种解决方法可能是:

long sum = 0;
object monitor = new object(); 
Parallel.For(1, 11, () => 0L, (i, state, local) => 
{ 
    long result = 1;

    for (long j = 1; j <= i; j++)
    {
        result = result*j;
    } 
    return local + result;
}, local => { lock (monitor) sum += local; }); 
Run Code Online (Sandbox Code Playgroud)

请注意,您很少需要两个嵌套Parallel.For循环,因为它们通常会导致性能不佳.因此Parallel.For,建议在最外层使用一个循环并保持内for循环.另外,要获得一些加速,你必须测试比大得多的数字10.