首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用MPI-IO写入多个共享文件

用MPI-IO写入多个共享文件
EN

Stack Overflow用户
提问于 2017-02-24 04:58:07
回答 3查看 1.3K关注 0票数 0

我正在运行一个具有数千个MPI进程的模拟,并且需要将输出数据写入一小组文件。例如,尽管我可能有10000个进程,但我只想写出10个文件,每个文件都有1000个写入文件(在适当的偏移量下)。正确的方法是为将要写入相同文件的进程组创建一个新的通信器,使用MPI_File_open()为该通信器打开一个共享文件,然后使用MPI_File_write_at_all()写入该文件。对吗?下面的代码是我编写的一个玩具示例:

代码语言:javascript
复制
#include <mpi.h>
#include <math.h>
#include <stdio.h>

const int MAX_NUM_FILES = 4;

int main(){
    MPI_Init(NULL, NULL);

    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    int numProcs;
    MPI_Comm_size(MPI_COMM_WORLD, &numProcs);

    int numProcsPerFile = ceil(((double) numProcs) / MAX_NUM_FILES);
    int targetFile = rank / numProcsPerFile;

    MPI_Comm fileComm;
    MPI_Comm_split(MPI_COMM_WORLD, targetFile, rank, &fileComm);

    int targetFileRank;
    MPI_Comm_rank(fileComm, &targetFileRank);

    char filename[20]; // Sufficient for testing purposes
    snprintf(filename, 20, "out_%d.dat", targetFile);
    printf(
        "Proc %d: writing to file %s with rank %d\n", rank, filename,
        targetFileRank);

    MPI_File outFile;
    MPI_File_open(
        fileComm, filename, MPI_MODE_CREATE | MPI_MODE_WRONLY,
        MPI_INFO_NULL, &outFile);

    char bufToWrite[4];
    snprintf(bufToWrite, 4, "%3d", rank);

    MPI_File_write_at_all(
        outFile, targetFileRank * 3,
        bufToWrite, 3, MPI_CHAR, MPI_STATUS_IGNORE);

    MPI_File_close(&outFile);
    MPI_Finalize();
}

我可以用mpicc file.c -lm编译,比如用mpirun -np 20 a.out运行20个进程,并得到预期的输出(四个文件,每个文件有五个条目),但我不确定这是否是技术上正确/最优的方法。有什么不一样的地方吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-03-04 04:48:59

你的方法是正确的。为了澄清,我们需要重新审视标准和定义。来自MPI_File_Open MPI:消息传递接口标准版本2.2的API (第391页)

int MPI_File_open(MPI_Comm comm,char *filename,int amode,MPI_Info info,MPI_File *fh)

描述:

MPI_FILE_OPEN在comm通信器组中的所有进程上打开由文件名文件名标识的文件。MPI_FILE_OPEN是一个集体例程:所有进程必须为amode提供相同的值,所有进程都必须提供引用相同文件的文件名。(信息的值可能有所不同。)通信必须是intracommunicator;,将intercommunicator传递给MPI_FILE_OPEN是错误的。

内部通信者与相互通信者(第134页):

为了本章的目的,只需知道有两种类型的传播者:内部传播者和相互传播者。内部通信程序可以被看作是与上下文关联的单个进程组的标识符。互连器标识与上下文关联的两组不同的进程。

将内部intracommunicator传递给MPI_File_open()的目的是指定一组将对文件执行操作的进程。MPI运行时需要这些信息,因此当集体I/O操作发生时,它可以强制执行适当的同步。程序员有责任理解应用程序的逻辑,并创建/选择正确的内部通信程序。

一个功能强大的API中的MPI_Comm_Split(),它允许将一个通信组分成不相交的子组,用于不同的用例,包括MPI /O。

票数 1
EN

Stack Overflow用户

发布于 2017-02-24 22:04:04

MPI_File_write_at_all应该是实现这一目标的最有效方法。对于大型、非连续的并行写入共享文件,集体IO函数通常是最快的,而_all变体将查找和写入合并到一个调用中。

票数 1
EN

Stack Overflow用户

发布于 2017-03-09 18:16:46

我认为这可能是上面的一个错误,但表示集体操作的是"_all“。

但是,我想指出的主要一点是,集体操作速度更快的原因是它们使I/O系统能够从许多进程聚合数据。您可能会从1000个进程发出1000次写入,但是使用集合形式,可以将其聚合为对文件的单个大写入(而不是1000次小写入)。当然,这是最好的情况,但对于我所见过的共享文件的访问,集体I/O的速度是非集体的1000倍,当然,对于比这更复杂的IO模式,这种改进可能是戏剧性的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42431064

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档