我需要帮助将C代码转换为MPI

时间:2016-12-22 19:13:47

标签: c mpi

我现在有一个带有MPI运行时的SGE集群。作为初学者,我希望有人帮助我将C代码转换为MPI,以便稍后使用SGE队列系统运行它,但我不明白。

我在C:

中添加了顺序代码
int initialize (double **A, int n)
{
   int i,j;
   for (j=0;j<n+1;j++){
     A[0][j]=1.0;
   }
  for (i=1;i<n+1;i++){
  A[i][0]=1.0;
  for (j=1;j<n+1;j++) A[i][j]=0.0;
   }

1 个答案:

答案 0 :(得分:1)

让我们专注于我理解的代码的相关部分(删除printf后可能错误的iters++):

for (for_iters=1;for_iters<21;for_iters++) 
{ 
    diff = 0.0;
    for (i=1;i<n;i++)
    {
        for (j=1;j<n;j++)
        {
            tmp = A[i][j];
            A[i][j] = 0.8*(A[i][j] + A[i][j-1] + A[i-1][j] + A[i][j+1] + A[i+1][j]);
            diff += fabs(A[i][j] - tmp);
        }
    }
    if (diff/((double)N*(double)N) < Tolerance)
    {
        convergence=TRUE;
    }
}

除了这个问题可能太少,无法证明并行化和分发算法所需的额外工作,基本问题是两个方向都存在数据依赖性:A [i] [j的新值]取决于A [i] [j]的旧值和:

  • A [i-1] [j]和A [i] [j-1]的新值;和
  • A [i + 1] [j]和A [i] [j + 1]
  • 的旧值

由于这些依赖关系是双向的,因此您最终会按照操作的顺序获得非常强大的约束:

  • A [i] [j + k]的新值的计算必须在A [i] [j]之后针对所有k> 0进行;和
  • A [i + 1] [j]的新值的计算必须在A [i] [j + 1]
  • 之后进行

通过这些约束,您可以想象在N个进程上并行执行,其中每个进程将计算给定值i的新值,但是您需要将第i行的处理器与第i行的处理器同步1。

从概念上讲,它可能是这样的:

double line_processor(int i, double **A, int n)
{
    // MPI: initialize communication with line processor for i-1
    // MPI: initialize communication with line processor for i+1
    double diff = 0.0;
    for (int j=1;j<n;j++)
    {
        double tmp = A[i][j];
        // MPI: wait for A[i-1][j+1] to be calculated
        // MPI: get the new value of A[i-1][j]
        A[i][j] = 0.8*(A[i][j] + A[i][j-1] + A[i-1][j] + A[i][j+1] + A[i+1][j]);
        // MPI: signal that A[i][j] has been calculated
        diff += fabs(A[i][j] - tmp);
    }
    // MPI: send the local value of diff for accumulation on the master process
    return diff;
}

不幸的是,围绕计算A [i] [j]的MPI等待和信令将比计算本身花费更多的时间,这将导致计算资源的使用效率极低,几乎可以肯定执行速度较慢而不是顺序实施。

传输数据和同步进程的MPI语法的细节可能最好留在相关教程中,而不是复制/粘贴。

如果你有一个非常大的大矩阵,那么重新审视这个问题并考虑切割矩阵会很有意义。