gpt4 book ai didi

performance - Fortran 未格式化 I/O 优化

转载 作者:行者123 更新时间:2023-12-05 08:34:21 24 4
gpt4 key购买 nike

我正在开发一组严重受 I/O 限制的 Fortran 程序,因此我正在尝试对其进行优化。我读过 multiple places写入整个数组比单个元素更快,即 WRITE(10)arrDO i=1,n;写(10) arr(i);结束。但是,我不清楚我的案子在这方面会落在哪里。从概念上讲,我的代码是这样的:

OPEN(10,FILE='testfile',FORM='UNFORMATTED')
DO i=1,n
[calculations to determine m values stored in array arr]
WRITE(10) m
DO j=1,m
WRITE(10) arr(j)
ENDDO
ENDDO

但是 m 每次通过 DO i=1,n 循环都会改变,这样写整个数组 arr 就不是一个选项。因此,折叠用于写入的 DO 循环将以 WRITE(10) arr(1:m) 结束,这与写入整个数组不同。这仍然可以提高写作速度吗?阅读呢?我可以在计算后分配一个大小为 m 的数组,将值分配给该数组,写入它,然后释放它,但这似乎太复杂了。

我还看到了关于隐式 DO 循环写入的不同信息,即 WRITE(10) (arr(j),j=1,m),关于它们是否帮助/伤害了我/O 开销。

我现在正在运行几个测试,并打算更新我的观察结果。其他适用的建议

其他详细信息:

  • 第一个程序创建一个大文件,第二个程序读取它。而且,不,合并这两个程序并将所有内容保存在内存中不是一个有效的选择。
  • 我正在使用未格式化的 I/O,并且可以访问 Portland Group 和 gfortran 编译器。据我了解,PG 通常速度更快,所以这就是我正在使用的。
  • 输出文件目前约为 600 GB,代码需要几个小时才能运行。
  • 第二个程序(读取文件)似乎特别昂贵。我监视了系统,发现它主要受 CPU 限制,即使我将代码减少到只读取文件,这表明在读取每个值时所有 I/O 调用的 CPU 开销非常大一次一个。
    • 编译器标志:-O3(高度优化)-fastsse(各种性能增强,针对 SSE 硬件进行了优化)-Mipa=fast,inline(在编译器上启用积极的过程间分析/优化)

更新我用 WRITE(10) arr(1:m)READ(10) arr(1:m) 运行代码。我对这些进行的测试表明,WRITE 代码的运行时间减少了大约 30%,输出文件的大小也略小于原始文件的一半。对于第二个代码,读取文件,我让代码基本上什么都不做,只是读取文件来比较纯读取时间。这将运行时间缩短了 30 倍。

最佳答案

如果您使用普通的未格式化(面向记录的)I/O,您还会在数据本身之前和之后写入一个记录标记。因此,您向每个数据项添加八个字节(通常)的开销,如果您的数字是 double ,这可以轻松(几乎)将写入光盘的数据加倍。其他答案中提到的运行时开销也很重要。

如果您使用未格式化的流,则上述论点不适用。

所以,使用

  WRITE (10) m
WRITE (10) arr(1:m)

对于 gfortran,这比隐含的 DO 循环(即解决方案 WRITE (10) (arr(i),i=1,m))更快。

在建议的解决方案中,构建一个数组描述符并通过一次调用将其传递给库。然后可以更有效地完成 I/O,在您的情况下利用数据是连续的这一事实。

对于隐含的 DO 循环,gfortran 发出多个库调用,开销很多。这可以优化,并且是长期错误报告的主题,PR 35339 ,但一些复杂的极端情况和可行替代方案的存在阻碍了它的优化。

我还建议在流访问中执行 I/O,不是因为节省的空间相当微不足道(见上文),而是因为保持领先的记录标记在写入时保持最新需要查找,这是额外的工作。

如果您的数据非常大,超过 ~ 2^31 字节,您可能会遇到不同的记录标记行为。 gfortran 在这种情况下使用子记录(与英特尔兼容),但它应该可以正常工作。我不知道波特兰在这种情况下会做什么。

对于读取,当然可以读取 m,然后分配一个可分配数组,然后在一条 READ 语句中读取整个数组。

关于performance - Fortran 未格式化 I/O 优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28858561/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com