我找到了两种不同的方法来从数组中获取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;
}
这些是做同样的事情还是不同的事情?谢谢;)
答案 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
所以Max
比naiveMax
(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)
他们看起来做同样的事情,但效率很低。并行化的目的是提高可以独立执行的代码的速度。由于竞争条件,发现最大值(如此处实现)需要原子信号量/锁定实际逻辑...这意味着你正在旋转许多线程和相关资源,只是为了顺序执行代码... ...击败完全并行化的目的。