TPL和Parallel.for

时间:2013-02-05 13:34:27

标签: .net task-parallel-library

网上有人说下面的C#代码无法转换为某些Parallel.for(对于多核系统)是正确的吗?如果是,是否有更好的方法进一步优化它。感谢

            for (int i = 0; i < 4; i++)
            {
                var tmp = i;
                tasks[i] = Task.Factory.StartNew(() => Console.WriteLine(tmp));
            }

3 个答案:

答案 0 :(得分:1)

嗯,你最后没有Tast.WaitAll(tasks)Parallel.For会为你做,所以你没有做Parallel.For正在做的事情(除非你没有把那些代码放在你的问题中。如果是这样,那么下一行是你的代码看起来像Parallel.For循环)

Parallel.For(0,4, (i) => Console.WriteLine(i));

除此之外,我不明白为什么你不能将它转换为Parallel.For。这个人因为无法转换而给出了什么理由?

答案 1 :(得分:0)

由于我们没有外循环代码,所以我在黑暗中采取刺。如果您只是测量整体平均运行时间而不需要存储任务,则可以使用类似的方法来测量串行和并行版本:

var iterations = 100;
var stopwatch = new Stopwatch();

// Run Serial version
stopwatch.Start();    
for(int i = 0; i < iterations; i++)
{
    for (int i = 0; i < 4; i++)
    {
        Console.WriteLine(tmp);
    }
}

stopwatch.Stop();
var serialTime = stopwatch.ElapsedMilliseconds;
stopwatch.Reset();

// Run parallel version
stopwatch.Start();

for(int i = 0; i < iterations; i++)
{
    Parallel.For(0,4, (i) => Console.WriteLine(i));    
}

stopwatch.Stop();

var parallelTime = stopwatch.ElapsedMilliseconds;

Console.WriteLine("Serial took  : {0}ms", serialTime / (double)iterations);
Console.WriteLine("Parallel took: {0}ms", parallelTime / (double)iterations);

这可能不是测量加速的一个很好的测试,因为工作量很轻。您可以尝试调用具有更多开销的函数或类似Thread.Sleep之类的函数来模仿更多工作。另请参阅我在This StackOverflow Question的答案,了解如何衡量C#中Amdahl的法律加速。

答案 2 :(得分:0)

首先,关于您报告的错误:

  

未处理的异常:System.AggregateException:发生了一个或多个错误。 System.ArgumentExcpetion:tasks数组包括至少一个null元素paraemeter名称:Tasks

错误很明显,它是由Task.WaitAll调用引发的 - 它表示tasks数组中的一个任务位置为空。

其次,衡量Console.WriteLine的效果有两个原因:

  1. 工作量太轻:我猜测设置开销会使实际工作相形见绌;
  2. Console.WriteLine已同步 - 意味着所有任务将开始,然后立即同步 - 使用map reduce API的情况绝对不合适。只需设计一个真实的计算工作量(例如计算素数);