c++ - MPI二进制文件I/O基本功能和性能问题

标签 c++ for-loop mpi

TLDR

当我并行生成文件时,For 循环挂起。为什么? (见下面的代码)此外,写入多个二进制文件(指针和偏移量由迭代变量确定)的安全/有效方法是什么?

背景和问题:

我希望我的代码执行以下操作:

(1) 所有进程都读取一个包含 double 矩阵的二进制文件 -> 已经使用 MPI_File_read_at() 实现了这一点

(2) 对于每个“列”的输入数据,使用每个“行”中的数字执行计算,并将每一列的数据保存到它自己的二进制输出文件中(“File0.bin” -> column 0)

(3) 为了使用户能够指定任意数量的进程,我使用简单的索引将矩阵视为一个长(行)X(列) vector ,并按进程数拆分该 vector 。每个进程获取 (rows)X(cols)/tot_proc 要处理的条目...使用这种方法,列不会被每个进程整齐地划分,因此,每个进程需要访问与其对应的任何文件,并且,使用适当的偏移量,写入正确文件的正确部分。目前,生成的文件是否碎片化并不重要。

在我朝着这个目标努力的过程中,我编写了一个简短的程序来循环创建二进制文件,但循环在最后一次迭代时挂起(13 个文件分为 4 个进程)。要创建的文件数 =(行)。

问题 1 为什么这段代码会在循环的最后挂起?在我的 4 个进程的玩具示例中,id_proc 1-3 有 3 个文件要创建,而 id_proc 0(根进程)有 4 个文件要创建。当根进程试图创建它的第 4 个文件时,循环挂起。注意:我正在使用 mpic++ 在运行 Ubuntu 的笔记本电脑上编译它。

问题 2 最后,我将添加第二个 for 循环,就像您在下面看到的那样,除了在这个循环中,进程必须写入已创建的二进制文件的适当部分.我计划使用 MPI_File_write_at() 来执行此操作,但我还读到文件应该使用 MPI_File_set_size() 静态调整大小,然后,每个进程都应该使用 MPI_File_set_view() 拥有自己的文件 View 。所以,我的问题是,为了让它发挥作用,我应该执行以下操作吗?

(循环 1)MPI_File_open(...,MPI_WRONLY | MPI_CREATE,...), MPI_File_set_size(), MPI_File_close()

(循环 2)MPI_File_open(...,MPI_WRONLY,...), MPI_File_set_view(), MPI_File_write_at(), MPI_File_close()

.... 循环 2 似乎会因为每次迭代都必须打开和关闭文件而变慢,但我事先不知道用户将提供多少输入数据,也不知道用户将提供多少进程。例如,进程 N 可能需要写入文件 1 的末尾、文件 2 的中间和文件 8 的末尾。原则上,所有这些都可以通过偏移来处理。我不知道 MPI 是否允许这种级别的灵 active 。

尝试并行创建多个文件的代码:

#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <vector>
#include <fstream>
#include <string>
#include <sstream>
#include <cmath>
#include <sys/types.h>
#include <sys/stat.h>
#include <mpi.h>

using namespace std;

int main(int argc, char** argv)
{
    //Variable declarations
    string oname;
    stringstream temp;
    int rows = 13, cols = 7, sz_dbl = sizeof(double);
    //each binary file will eventually have 7*sz_dbl bytes
    int id_proc, tot_proc, loop_min, loop_max;
    vector<double> output(rows*cols,1.0);//data to write

    //MPI routines
    MPI_Init(&argc,&argv);//initialize MPI
    MPI_Comm_rank(MPI_COMM_WORLD,&id_proc);//get "this" node's id#/rank
    MPI_Comm_size(MPI_COMM_WORLD,&tot_proc);//get the number of processors

    //MPI loop variable assignments
    loop_min = id_proc*rows/tot_proc + min(rows % tot_proc, id_proc);
    loop_max = loop_min + rows/tot_proc + (rows % tot_proc > id_proc);

    //File handle
    MPI_File outfile;

    //Create binary files in parallel
    for(int i = loop_min; i < loop_max; i++)
    {
        temp << i;
        oname = "Myout" + temp.str() + ".bin";
        MPI_File_open(MPI_COMM_WORLD, oname.c_str(), MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &outfile);
        temp.clear();
        temp.str(string());
        MPI_File_close(&outfile);
    }
    MPI_Barrier(MPI_COMM_WORLD);//with or without this, same error

    MPI_Finalize();//MPI - end mpi run
    return 0;
}

到目前为止我已阅读的教程/信息页面:

http://beige.ucs.indiana.edu/B673/node180.html

http://beige.ucs.indiana.edu/B673/node181.html

http://mpi-forum.org/docs/mpi-2.2/mpi22-report/node305.htm

https://www.open-mpi.org/doc/v1.4/man3/MPI_File_open.3.php

http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node215.htm

Parallel output using MPI IO to a single file

Is it possible to write with several processors in the same file, at the end of the file, in an ordonated way?

最佳答案

MPI_File_open() 是一个集体操作,这意味着来自MPI_COMM_WORLD 的所有任务必须在相同的时间打开相同 文件时间。

如果您想为每个任务打开一个进程,请改用 MPI_COMM_SELF

关于c++ - MPI二进制文件I/O基本功能和性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44711715/

相关文章:

linux - For-loop + echo 改变了我输出的所需格式

r - 如何在R中更有效地拾取和排序?

c++ - 静态变量可以多次初始化吗?

C# for循环逐行写入

使用opencv进行c++视频捕获

c++ - 'parallelize'这个程序有可能吗?

azure - 将多次运行提交到 AzureML 上的同一节点

c++ - 由于某种原因必须发送 MPI 消息两次

c++ - 什么是基于集合的数据结构

C++ Ifstream 对象等于 nullptr 但它不是指针?