Fortran中并行读取可以提高性能吗?

5
我有一个Fortran90代码,大部分时间都用于I/O,因为需要读取非常大的数据文件(至少1GB及以上)。还需要写入一些较小但仍然很大的计算结果数据文件。相比之下,一些快速傅里叶变换和其他计算可以在短时间内完成。我已经使用并行化(OpenMP)来处理其中的一些计算,但由于上述I/O问题,整体性能提升非常有限。

我目前的策略是一次性读取整个文件:

open(unit=10, file="data", status="old")

do i=1,verylargenumber
  read(10,*) var1(i), var2(i), var3(i)
end do

close(10)

然后对var1等执行操作。我的问题是,是否有一种适合使用(最好是)OpenMP的策略,可以加速读取过程,特别是考虑到数据文件非常大的情况下(如果有任何区别)。
我有可能在Lustre文件系统上运行这些计算,这原则上为并行I/O提供了优势,尽管希望能够提供常规文件系统的通用解决方案。
我的直觉是没有解决这个问题的方法,但我想确认一下。

5
同时从两个线程读取(或写入)同一文件很可能会导致争用,因为它们都要访问RAM和磁盘表面之间的单个I/O硬件通道。(除非您拥有并行硬件级磁盘系统。)一般来说,您当前的方法——一次性读取(和写入)大型文件——通常是最好的方法。您可以通过将输入/输出缓冲区大小精确匹配到要处理的内存块来提高性能,但这将使您远离Fortran。还有其他技巧,但同样超出了Fortran的范围。 - High Performance Mark
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Miguel
3
文件必须是可读的吗?如果不需要,使用未格式化的文件(有时称为“二进制”)可以获得更快的性能。在打开语句中使用form ='unformatted'。大部分运行时间可能花费在字符和数字内部表示之间的转换上。 - M. S. B.
@M.S.B. 谢谢,这可能真的有帮助。这些文件通常以分子动力学模拟的典型格式提供,有时是ASCII格式,有时是二进制格式。我想我可以编写一个小接口,允许用户使用二进制文件并提高性能。 - Miguel
你也可以将文件分割成多个独立的文件。现在,每个线程可以读取不同的文件。如果你能够将文件放置在不同的物理硬盘上,你将从并行化中获益。 - Anthony Scemama
显示剩余2条评论
1个回答

0

我不是Fortran大师,但看起来你正在以非常小的块(每次3个整数,最多几十个字节)从文件中读取值。一次性以大块(多兆字节)读取文件将显著提高性能,因为您将通过多个数量级减少底层read()系统调用(和相应的锁定开销)。

如果您的大文件是在Lustre中使用多个条带(例如,在目录中使用lfs setstripe -c 8 -S 4M <dir>设置默认条带计数为8,对于该目录中的所有文件,条带大小为4MB),那么这可能会提高聚合读取性能-假设您一次只读取一个文件,并且您没有受到客户端网络带宽的限制。如果您的程序在多个节点和/或线程上同时运行,并且每个线程都在读取自己的文件,则您已经具有文件级别以上的并行性。即使从单个文件中读取也可以很好地完成(如果读取很大),因为Lustre客户端将在后台执行预读。

如果您有多个计算线程同时处理文件的不同块(例如4MB块),那么您可以从不同的线程中读取每个4MB块,这可能会提高性能,因为您将有更多的IO请求在运行。但是,单个客户端从网络读取文件的速度仍然存在限制。从多个客户端并发地读取多条带文件将允许您聚合来自多个客户端和服务器的网络和磁盘带宽,这正是Lustre表现最佳的地方。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接