0

我正在尝试改进并行性。在我的主要代码部分中。这个循环有主要的计算,每个输出需要做超过 100 万次(我需要 8000 万次输出)。因此,即使是轻微的改进,也会对执行时间产生严重影响。我知道 IF 条件会降低并行计算速度。另外,我知道特殊位置的主要变量(U[i,j] 和 V[i,j])可能始终为零。因此,如果我可以为这些数组的特殊列分配常数零(不想改变计算),我可以从代码中消除 IF 条件。

Before calculation:
| 1 1 1 0 1|
| 1 1 1 0 1|
| 1 1 1 0 1|
| 1 1 1 0 1|
After calculation:
| 3 1 8 0 5|
| 1 4 4 0 1|
| 7 3 1 0 8|
| 1 1 5 0 7|

我想要一个其值始终为零的列。

如何为二维数组的空间列分配常数(零)?

作为示例,上述部分如下所示:

double[,] U= new double[nx,ny];
double[,] V= new double[nx,ny];

Parallel.For(0,nx,i =>
{
   For (j=0; j<ny ; j++)
   {
     if (i!=a && i!=b &&i!=c &&i!=d &&)
     {
       U[i,j]= ...; // A big chunk of calculations
       V[i,j]=... ;// A big chunk of calculations
     }
  }
}

有趣的是,当我运行代码时,我发现它使用了几乎 20% 的内核。是因为我的并行循环较弱还是我应该手动分配循环使用的内核数?

4

2 回答 2

4

这难道不能有所改善吗?

Parallel.For(0,nx,i =>
{
   if (i!=a && i!=b &&i!=c &&i!=d &&)
   {
       For (j=0; j<ny ; j++)
       {
           U[i,j]= ...; // A big chunk of calculations
           V[i,j]=... ;// A big chunk of calculations
       }
   }
}

i只有在不满足条件时才评估内部循环。否则,您实际上处于忙碌的等待状态。

于 2014-08-06T00:58:08.897 回答
0

在单独的内核中计算边界,因为只有它们有“if”子句。然后计算没有任何 if 条件的内部。预计 2 倍加速。

//interior (dont include borders)
Parallel.For(1,nx-1,i =>
{

       For (j=1; j<ny-1 ; j++)
       {
           U[i,j]= ...; // A big chunk of calculations
           V[i,j]=... ;// A big chunk of calculations
       } 

}

//exterior 1
Parallel.For(xx,xx1,i =>
{
   //another calculation
}

//exterior 2
Parallel.For(xx1,yy,i =>
{
   //another calculation
}

//exterior 3
Parallel.For(yy,yy1,i =>
{
   //another calculation
}

//exterior 4
Parallel.For(yy1,xx,i =>
{
   //another calculation
}

使用 C++ dll 进行内循环,甚至可以为 gpgpu 提供 10 倍的加速(SIMD)——> 30 倍的加速。

于 2014-08-06T09:40:19.583 回答