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

时间:2011-12-03 20:51:44

标签: 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;
}

并行编码:

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;
    });

请以正确的方式告诉我

for (long i = 1; i <= 5; i++)
        {
            sum = sum * i;
        }

Parallel.For(1, 5, delegate(int i)
    {
        sum = sum * i;
    });

parallel = 24

的结果

正常结果= 120

2 个答案:

答案 0 :(得分:5)

并行版本中的答案是任意的,因为sumresult由不同的线程访问和修改。所以你应该做的是分开计算每一步和总结结果。为了能够正确地总结结果,您需要获取一个锁,以便线程专门修改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; }); 

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

答案 1 :(得分:0)

我找到了一种快速计算平行因子的方法。

    public static BigInteger Factorial(int n)
    {
        BigInteger temp = 1;

        Parallel.For(1, n + 1, (i) =>
        {
            temp *= i;
        });

        return temp;
    }