将堆栈或堆用于MPI程序变量

时间:2017-03-10 09:22:25

标签: c stack mpi heap

我最近开始使用英特尔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变量。

0 个答案:

没有答案