在上一篇中我们介绍了 mpi4py 中的非阻塞 I/O 操作,下面我们将介绍 mpi4py 中的共享文件指针 I/O 操作。
共享文件指针
每个通过 MPI.File.Open 打开的文件,除了每个进程所拥有的独立文件指针之外,还存在一个全局唯一的为每个进程所共享的共享文件指针。共享文件指针也是以相对于进程当前文件视图的相对位置计算,并且共享文件指针和每个进程的独立文件指针是相互独立,互不影响的。使用共享文件指针 I/O 操作方法要求所有的进程必须使用相同的文件视图,每个进程对共享文件指针读/写方法的一次调用都会将共享文件指针从当前位置移动到加上所读/写数据量的新位置,即各个进程对共享文件指针读/写方法的多次调用的实际效果相当于将这些进程的每次调用按一定的顺序串行化后执行的累加,但对非集合方法调用,这种串行化的顺序是不确定的,如果需要保证某种确定的顺序,则应用程序需使用其他机制,如同步操作等,来保证串行顺序的确定性。共享文件指针的集合操作(包括分步集合操作)访问文件顺序默认为按照进程 rank 从小到大顺序排列,排在后面的进程使用排在前面的进程更新过的共享文件指针访问数据。为防止相同进程再次发起共享文件指针操作打乱当前的执行,MPI 要求只有参加集合操作的所有进程都返回后才可发起下一个共享文件指针操作。这个规定只是从语义上保证共享文件指针操作的顺序性。实际上,具体实现时可以根据进程编号和调用参数计算出每个进程要访问的文件位置,从而可在底层调用显式偏移地址或独立文件指针 I/O 方法使之依然高效地并行执行。
共享文件指针定位操作
打开文件的进程组可以显式地通过 MPI.File.Seek_shared 来移动共享文件指针,其方法接口如下:
MPI.File.Seek_shared(self, Offset offset, int whence=SEEK_SET)
移动共享文件指针到指定偏移位置 offset
。该方法是一个集合操作,根据 whence
参数更新共享文件指针。whence
的可能取值如下:
- MPI.SEEK_SET:将文件指针设置为指向
offset
参数设置的位置; - MPI.SEEK_CUR:将文件指针设置为指向当前指针加上
offset
参数值之后的位置; MPI.SEEK_END:将文件指针设置为指向文件末尾再加上
offset
参数值之后的位置。MPI.File.Get_position_shared(self)
返回共享文件指针相对当前文件视图的位置(以 etype 为单位)。
使用共享文件指针的读/写操作方法接口如下:
阻塞共享文件指针 I/O 操作
非集合操作
MPI.File.Read_shared(self, buf, Status status=None)
MPI.File.Write_shared(self, buf, Status status=None)
集合操作
使用共享文件指针的阻塞集合操作被命名为 xxxx_ordered 是因为其访问文件的顺序默认是按照进程 rank 从小到大的顺序排列的。
MPI.File.Read_ordered(self, buf, Status status=None)
MPI.File.Write_ordered(self, buf, Status status=None)
注意:对阻塞共享文件指针 I/O,