2

我正在将现有的 MPI 代码转换为混合 MPI/OpenMP 以解决性能和可伸缩性问题。在原始 MPI 代码中,我使用了集体 MPI I/O(特别是 MPI_File_write/read_at_all),现在我将其转换为混合模式,我不知道如何在不损失性能的情况下使用 I/O。我目前使用的系统有多个 32 核的节点,我的计划是每个节点运行 1 个 MPI 进程,每个节点内运行 32 个线程。系统和编译器 (PGI) 支持 MPI_THREAD_MULTIPLE 并具有基于 Lustre 的并行文件系统。我的代码是这样的:

#include "mpi.h"
#include "omp.h"
#define NTHREADS 32
int main()
{
    int provided;
    int myrank,numproc,tid;
    double b[BIGSIZE]={0.};
    int iter,i;

    MPI_Init_thread( 0, 0, MPI_THREAD_MULTIPLE, &provided );
    omp_set_num_threads(NTHREADS);

    /* Initialize b */

    #pragma omp parallel private(i,some variables)\
                         shared(b and some other stuffs)\
                         default(none)
    {
        /* Inside each thread: */
        for (i=0;i<iter;i++)
        {
            /* each thread of each process do work on few elements of variable b */
            /* 2 threads do less work and communicate with the other processes  */
            /* Write the variable b's of all MPI processes in one file */
            /* b is actually divided between MPI processes and then is divided
               between threads inside each process, so the work is distributed */
            /* write operation MUST be complete before the next iteration starts */
        }
    }
    MPI_Finalize();
    return 0;
}

现在我的问题是如何处理写入部分以获得最佳性能,我是一名机械工程师,所以不熟悉可能的解决方案。在开始研究之前,我想看看是否有类似案例的标准方法,我的想法是:

  1. 在每个线程中使用 MPI_File_write_at 并忘记集体版本,(我不确定这是否真的正确,我可以使用 MPI_Barrier 和 omp_barrier 等待完成吗?),我将如何定义文件指针?私有的还是共享的?
  2. 在主指令的主线程中使用 MPI_File_write_at_all 并使用屏障保持其余线程空闲。
  3. 还有其他可能的方式吗?

代码的性能和可扩展性对我来说真的很重要,我需要你们的帮助!

谢谢

4

1 回答 1

2

我认为您过早地针对您可能没有的问题进行了优化。

首先使计算与 OpenMP 并行,坚持一些 OpenMP 障碍并像以前一样继续执行 IO。

对代码进行基准测试/计时,如果 IO 成为性能的一大障碍,请尝试优化。您可能会发现您建议的内容实际上比集体版本的性能更差。无论哪种方式,在优化之前对您当前的性能进行量化处理。

如果您迫切需要速度,您可以做的最快和最简单的事情之一就是将每个线程写入一个单独的文件,然后在后处理中合并这些文件。我觉得这很hacky,所以将它作为最后的手段。

于 2012-11-13T07:02:21.983 回答