我有2
处理器(这是一个例子),我希望这些2
处理器写入一个文件。我希望他们写在文件的末尾,但不是混合模式,就像这样:
[file content]
proc0
proc1
proc0
proc1
proc0
proc1
(and so on..)
我想让他们按照这种模式写:
[file content]
proc0
proc0
proc0
proc1
proc1
proc1
(and so on..)
可能吗?如果是这样,要使用的设置是什么?
您的流程准备好报告输出的顺序基本上是事先不可知的。即使重复运行完全相同的 MPI 程序也会显示输出顺序的差异。因此,某处的某些东西将不得不对文件的写入施加顺序。
Wesley 已经提到的一种非常常见的模式是让所有进程将它们的输出发送到一个进程,通常是进程 0,并让它处理写入文件。这个主编写器可以在写入之前对输出进行排序,但这会产生一些问题:在写入之前分配空间来存储输出,并且更难处理的是,确定何时可以对输出记录的集合进行排序并写入文件以及输出缓冲区被重用。master-writer 等待多长时间,它如何知道一个进程是否仍在工作?
因此,通常让主编写器在获取输出时写入输出,而另一个程序在并行程序完成后根据需要对输出文件进行排序。您可以将其添加到您的并行程序中作为后续步骤,mpi_finalize
或者您可以使用完全独立的程序(例如sort
在 Linux 机器上)。当然,为此,每个输出记录都必须包含一些排序信息。
另一种常见的模式是只有一个进程根本不进行任何写入,也就是说,其他进程根本不进行任何输出。这完全避免了写作顺序的不确定性。
另一种不太常见的模式是使用mpi io
. 多个进程可以像同时mpi io
写入文件的不同部分一样。要实际同时编写程序,需要在支持并行 i/o 的硬件、网络和操作系统上执行。即使使用正确的平台也很难实现这一点,尤其是当流程的输出量不确定时。
根据我在 SO 上的经验,即使他们可以访问必要的硬件,也可能在他们的 MPI 体验中处于太早的阶段,以解决并行 i/o 问题。
我不同意高性能标记。MPI-IO 在 2014 年并不是那么棘手(只要您可以访问除 NFS 之外的任何文件系统——如果您需要一个便宜且简单的并行文件系统,请安装 PVFS)。
如果您知道每个进程有多少数据,您可以使用 MPI_SCAN 有效地计算“早期”进程写入了多少数据,然后使用 MPI_FILE_WRITE_AT_ALL 有效地执行 I/O。这是您可以执行此操作的一种方法:
incr = (count*datatype_size);
MPI_Scan(&incr, &new_offset, 1, MPI_LONG_LONG_INT,
MPI_SUM, MPI_COMM_WORLD);
MPI_File_write_at_all(mpi_fh, new_offset, buf, count,
datatype, status)
你的问题的答案是否定的。如果你这样做,你最终会得到来自各地的混乱输出。
但是,您可以通过将输出发送到单个处理器并让它自己完成所有写入来获得相同的结果。例如,在您的应用程序结束时,只需将所有内容发送到 rank 0 并让 rank 0 将其全部写入文件。