0

假设我有 N 个文件,格式如下:

一个文件看起来像这样:
每次都有一些具有不同 id 的数据

- time 1:
      -  data with id: 10
      -  data with id: 13
      -  data with id: 4
- time 2:
      -  data with id: 10
      -  data with id: 77
...etc

(每次ID为1-1000的数据都以某种方式(混合)分布在这些N个文件中)

我想合并所有这些 N 个文件,以便我有一个有序的文件:

最终文件:

- time 1:
       -  data with id: 1
       -  data with id: 2
       -  data with id: 3
       -  ...
       -  data with id: 1000

- time 2:
       -  data with id: 1
       -  data with id: 2
       -  data with id: 3
       -  ...
       -  data with id: 1000
...etc

数据 id 1-1000 的大小约为 100mb,但我有很多次最多占 50 GB 的数据。

我对这个问题的解决方案是这样的,以使其尽可能快:

我在超级计算机节点(例如 24-48 核的 1 台计算机)上使用T 线程(例如)。我已经分配了一个共享内存数组来保存所有 ids 1 - 1000 的数据一次(如果我愿意,也可以更多)

程序:
步骤 1:

  • 每个线程都有一些它打开并拥有的文件。然后每个线程将其在文件中的 id 数据填充到共享数组中。

第2步:

  • 当所有线程最终处理一次时 --> 线程 1 将这个数组以有序的形式写入最终文件。

阿斯达斯

  1. 如果这有效,我会非常感兴趣?并行读取是否无论如何都没有顺序化,所以它根本没有用?我可以在具有超快 SSD 的本地计算机或具有网络存储(Lustres 或 Panasas 文件系统)的集群节点上计算最终文件
  2. 我可以在第 2 步中再次使用所有线程并行写入磁盘,比如说使用 MPI IO(它支持通过偏移量并行写入),或者如何实现?-> C++ 标准库?

感谢您的任何投入!

4

1 回答 1

1

您的方法可能适用于中等数量的数据,但您已将排名设为此处交流的中心点。这不会很好地扩展。

您的第 2 部分走在正确的轨道上:使用 MPI-IO 的并行写入对我来说听起来是一个好方法。以下是可能的情况:

  1. 继续让你的 T 进程读取它们的输入。
  2. 我将假设“id”是密集分配的。我的意思是,在这个文件集合中,一个进程能否知道它是否看到data with id: 4其他一些进程的 id 为 1、2、3 和 5 ?如果是这样,那么每个进程都知道它的数据必须去哪里。
  3. 我们还假设每个“数据”都是固定大小的。如果不是这种情况,这种方法只会稍微复杂一点。

如果您不知道最大 ID 和最大时间步长,则必须进行一些通信(以 MPI_MAX 作为操作的 MPI_Allreduce)才能找到它。

通过这些准备工作,您可以设置 MPI-IO“文件视图”,可能使用MPI_Type_indexed

在等级 0 上,这会变得有点复杂,因为您需要将时间步长标记添加到数据列表中。或者,您可以定义具有时间步长索引的文件格式,并将该索引存储在页眉或页脚中。

代码大致如下所示:

for(i=0; i<nitems; i++)
    datalen[i] = sizeof(item);
    offsets[i] = sizeof(item)*index_of_item;
}
MPI_Type_create_indexed(nitems, datalen, offsets, MPI_BYTE, &filetype);
MPI_File_set_view(fh, 0, MPI_BYTE, filetype, "native", MPI_INFO_NULL);
MPI_File_write_all(fh, buffer, nitems*sizeof(item), MPI_BYTE, &status);

这里的 _all 位很重要:您将从每个 MPI 处理器创建一个高度不连续、不规则的访问模式。让 MPI-IO 库有机会优化该请求。

还需要注意的是,MPI-IO 文件视图必须是单调非递减的,因此您必须先在本地对项目进行排序,然后再集体写出数据。相对于 I/O 操作,本地内存操作的成本微不足道,因此这通常不是什么大问题。

于 2013-11-05T15:58:31.660 回答