我现在有一个带有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;
}
答案 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]的旧值和:
由于这些依赖关系是双向的,因此您最终会按照操作的顺序获得非常强大的约束:
通过这些约束,您可以想象在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语法的细节可能最好留在相关教程中,而不是复制/粘贴。
如果你有一个非常大的大矩阵,那么重新审视这个问题并考虑切割矩阵会很有意义。