2013-02-05 54 views
0

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

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

你想用这个'tasks'数组做什么?这是你的一组实际任务,只需要向控制台写4次?至于4次迭代,您可能会因开始新线程而承受更多的开销,而不是从并行完成的工作中获得收益。 –

+0

只是FYI,Parallel.For有很多开销,所以除非你真的测量过并且发现速度更快,或者需要内置节流,否则我建议你循环使用Task.Run来完成工作你在做, –

回答

1

好了,你没有Tast.WaitAll(tasks)在年底,这Parallel.For愿意为你做,这样你就不太做什么Parallel.For在做什么(除非你有没有把这些代码在你的问题。如果是这样,则下一行是你的代码是什么样子的循环的Parallel.For)

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

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

+0

是的,我有TaskWaitAll,但我没有发布所有的代码。谢谢你的代码行! – user2023152

+0

它没有工作。它在运行过程中编译得很好但错误太多。 – user2023152

+0

你得到了什么错误? –

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法则加速。

+0

谢谢。这是一个很好的例子,但是其他性能原因需要完成这些任务。有没有办法通过电子邮件联系,所以我可以给你发送两个CPU利用率图,希望你能解释发生了什么? – user2023152

+2

最好更新您的问题并上传图表,以便每个人都能受益。 StackOverflow还有一个开放的聊天工具(这是公开的),这样每个人都可以受益 - 这就是本网站的重点。 –

0

首先,有关错误你报:

未处理的异常:System.AggregateException:一个或多个erroros发生。 System.ArgumentExcpetion:任务阵列inclue至少一个空元素paraemeter名称:任务

的错误是很清楚,它是由您的通话Task.WaitAll提出 - 它说,在你的tasks阵列任务插槽之一是空值。

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

  1. 工作量太亮:我猜测,设置开销将大大超过实际工作;
  2. Console.WriteLine是同步的 - 意味着所有的任务将开始,然后立即同步 - 这是使用地图缩小API绝对不适合的情况。只需设计一个真正的计算工作负载(例如计算素数);