假设我有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
(每次带有1-1000的ID的数据在这些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个核心的计算机)上使用 T个线程(例如)。 我已经分配了一个共享内存数组来保存所有数据,其中id为1 - 1000一次(如果我喜欢,也可以更多)
步骤:
第1步:
第2步:
asdasd
感谢您的任何意见!
答案 0 :(得分:1)
您的方法可能适用于适量的数据,但您已将此排名作为通信的中心点。这不会非常好地扩展。
你正处于第2部分的正确轨道:使用MPI-IO的并行写入听起来对我来说是一个好方法。这是怎么回事:
data with id: 4
某些其他进程的id为1,2,3和5?如果是这样,那么每个进程都知道它的数据必须去哪里。 如果您不知道最大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操作的成本微不足道,因此这通常不是什么大问题。