1

我在c#中有一个CFD(计算流体动力学),它需要太多的时间来计算结果。为了改进我的代码,我开始学习TPL并使用并行代码。对于顺序不重要的循环,我可以使用TPL和PLINQ命令的循环,这是唯一的方法。 我正确吗?为什么在C#中并行For循环比简单For循环需要更多时间?

作为第一步,我将For循环更改为Parallel.For,并且有趣地发现运行时间增加了!

样品我的代码:

for (int i = 0; i < nx; i++) 
{ 
    for (int j = 0; j < ny; j++) 
    { 
     if (!Cells[i, j, 0].IsVirtual) 
     { 
      // calculate x velocity 
      // calculate y velocity 

     } 
    } 
} 

随着并行任务:

Parallel.for (0,nx, i => 
{ 
    for (int j = 0; j < ny; j++) 
    { 
     if (!Cells[i, j, 0].IsVirtual) 
     { 
      // calculate x velocity 
      // calculate y velocity 
     } 
    } 
}); 

我怎样才能加快我的代码? 我的每个输出需要10分钟,这是非常长的时间,我至少需要5000个输出。

+1

需要提供实际的代码而不仅仅是一个骨架结构来确定其表现糟糕的原因。这可能是因为线程的开销超过了您的计算量(http://stackoverflow.com/questions/10763184/how-does-sequential-loop-run-faster-than-parallel-loop-in-c)。这可能是因为你使用了太多的全局变量(http://stackoverflow.com/questions/10846550/disappointing-performance-with-parallel-for)。这可能是因为您已将线程池大小设置得太低。或者其他一些原因,只有深入了解你正在做的事情才能发现。 – Sybeus

+0

你正在使用什么CPU?并行计算需要硬件支持。 – Johnny

+0

我有一个电脑与核心i7 CPU。 如果TPL无法帮助我提高计算速度,那么我的其他解决方案是什么? – user3803849

回答

3

对于小型循环来说,管理线程的开销可能会影响总体执行时间。如果每次迭代执行时间较长,您可能会看到不同的结果。

0

对于大型数据集(例如至少500,000个单元格),您可能会因缓存失效而遇到问题,因为您无法高效地遍历内存。

您可能会看到的性能提升,如果你改成这样(不管你是否或不使用TPL)(注意我如何翻转迭代从i,jj,i):

for (int j = 0; j < ny; j++) 
{ 
    for (int i = 0; i < nx; i++) 
    { 
     if (!Cells[i, j, 0].IsVirtual) 
     { 
      // calculate x velocity 
      // calculate y velocity 

     } 
    } 
} 

在这里看到的解释:Why does the order of the loops affect performance when iterating over a 2D array?

+0

你的意思是我没有办法提高我的代码速度? 我有超过100万个单元格,并且这部分代码的计算需要很长时间。关于其他平凡的For循环,我应用了TPL,但效果不佳,主循环对于节省时间非常重要。 – user3803849

+0

@ user3803849不,我没有这么说 – Dai