这种方法有什么作用?

时间:2013-06-28 14:31:41

标签: c# parallel-processing max

我找到了两种不同的方法来从数组中获取Max值,但我并不喜欢并行编程,所以我真的不明白它。

我想知道这种方法是做同样的还是我错过了什么? 我真的没有太多关于它们的信息。甚至没有评论...

第一种方法:

int[] vec = ... (I guess the content doesn't matter)

static int naiveMax()
{
    int max = vec[0];
    object obj = new object();

    Parallel.For(0, vec.Length, i =>
    {
        lock (obj) {
                if (vec[i] > max) max = vec[i];
        }
    });

    return max;
}

第二个:

static int Max()
{
    int max = vec[0];
    object obj = new object();

    Parallel.For(0, vec.Length,     //could be Parallel.For<int>
        () => vec[0],
        (i, loopState, partial) =>
    {
        if(vec[i]>partial) partial = vec[i];
        return partial;
    },
    partial => {
            lock (obj) {
                    if( partial > max) max = partial;
            }
    });
    return max;
}

这些是做同样的事情还是不同的事情?谢谢;)

2 个答案:

答案 0 :(得分:2)

两者都在整数数组中找到最大值。为了更快地找到最大值,他们使用Parallel.For Method“并行”地执行此操作。但是,这两种方法都失败了。

要看到这一点,我们首先需要一个足够大的整数数组。对于小型阵列,并行处理无论如何都不能提高速度。

int[] values = new int[100000000];
Random random = new Random();
for (int i = 0; i < values.Length; i++)
{
    values[i] = random.Next();
}

现在我们可以运行这两种方法,看看它们需要多长时间。使用适当的性能测量设置(Stopwatch,100,000,000个整数,100次迭代,发布构建,没有附加调试器,JIT热身)我在我的机器上得到以下结果:< / p>

naiveMax   00:06:03.3737078
Max        00:00:15.2453303

所以MaxnaiveMax(6分钟!咳嗽)更好

但是,与PLINQ相比,它是如何比较的?

static int MaxPlinq(int[] values)
{
    return values.AsParallel().Max();
}
MaxPlinq   00:00:11.2335842

还不错,保存了几秒钟。现在,用于比较的简单,旧的,顺序的for循环呢?

static int Simple(int[] values)
{
    int result = values[0];
    for (int i = 0; i < values.Length; i++)
    {
        if (result < values[i]) result = values[i];
    }
    return result;
}
Simple     00:00:05.7837002

我认为我们有一个胜利者。

获得的经验教训:Parallel.For不是你可以撒在代码上的小精灵 让它神奇地跑得更快。如果性能很重要,请使用正确的工具和度量,度量度量,......

答案 1 :(得分:0)

他们看起来做同样的事情,但效率很低。并行化的目的是提高可以独立执行的代码的速度。由于竞争条件,发现最大值(如此处实现)需要原子信号量/锁定实际逻辑...这意味着你正在旋转许多线程和相关资源,只是为了顺序执行代码... ...击败完全并行化的目的。