我最近开始使用英特尔MPI来并行化一个非常简单的流求解器。我想知道是否应该使用堆栈来存储我的变量(即使用datatype name[size];
进行声明)或堆(即使用datatype *name = (datatype *)malloc(size*sizeof(datatype));
)。
首先我使用malloc,因为我将流场分成n
部分,其中n
是创建的进程数,我认为使用相同的代码会很好n的所有值。这意味着我的数组的大小首先在运行时已知。因此我显然需要动态内存分配。到目前为止一切都很好。
但由于动态分配,这使整个计划变得非常缓慢。它甚至更慢,然后连续解决。
我修改了我的程序并使用了数组声明,并获得了预期的加速。但是现在我的程序无法适应不同的起始条件(例如,进程数,流场大小,网格点数......)。
任何人都可以建议解决这种困境的常见做法是什么?显然,世界上有很多流量求解器具有出色的性能,并且可以根据起始条件进行调整。
非常感谢!
编辑:我试图简化我的代码(虽然它不是MWE):
int main(int argc, char** argv)
{
int rank, numProcs, start, length, left, right;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
if (rank==0)
{
split_and_send_domain(&start, &length, &left, &right, numProcs);
// allocate memory for arrays like velocity, temperature,...
double x1[length]; // double *x1=(double *)malloc(length*sizeof(double));
double x2[length]; // double *x2=(double *)malloc(length*sizeof(double));
...
double xn[length]; // double *xn=(double *)malloc(length*sizeof(double));
// initialize variables like local residual, global residual, iteration step,...
int res = 1, resGlob=1; iter=0,...;
int keepOn = 1;
setupCalculation(start, length, left, right, x1, x2, ...); // initializes the arrays
MPI_Barrier(MPI_COMM_WORLD);
while (keepOn){
iter++;
pass_boundaries(left, right, length, utilde, rank);
do_calculation(length, x1, x2, ...);
calc_own_residual(length, x1, x2, ...);
calc_glob_residual(&resGlob, res);
if (iter>=maxiter || resGlob<1e-8) keepOn = 0;
MPI_Bcast(&keepOn, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
}
/* gather results & do some final calculations & output*/
}
else
{
receive_domain(&start, &length, &left, &right);
// allocate memory for arrays like velocity, temperature,...
double x1[length]; // double *x1=(double *)malloc(length*sizeof(double));
double x2[length]; // double *x2=(double *)malloc(length*sizeof(double));
...
double xn[length]; // double *xn=(double *)malloc(length*sizeof(double));
// initialize variables like residual, iteration step,...
int res = 1;
int keepOn = 1;
setupCalculation(start, length, left, right, x1, x2, ...); // initializes the arrays
MPI_Barrier(MPI_COMM_WORLD);
while (keepOn){
pass_boundaries(left, right, length, utilde, rank);
do_calculation(length, x1, x2, ...);
calc_own_residual(length, x1, x2, ...);
calc_glob_residual(&resGlob, res);
MPI_Bcast(&keepOn, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
}
}
MPI_Finalize();
}
当使用动态分配int length
时,在开头另外计算,否则将其设置为全局const变量。