【问题标题】:gfortran change/find out write buffer sizegfortran 更改/找出写入缓冲区大小
【发布时间】:2013-12-31 00:31:26
【问题描述】:

我有这个分子动力学程序,它在模拟的每 n 步将原子位置和速度写入文件。实际的写作需要大约 90% 的运行时间! (通过消除写入来检查)所以我迫切需要优化它。

我看到一些 fortrans 有一个扩展来改变写缓冲区大小(称为 i/o 块大小)和 OPEN 语句中的“块数”,但似乎 gfortran 没有。我还在某处读到 gfortran 使用 8192 字节的写入缓冲区。

我什至尝试做一个 FSTAT(在打开之后,对吗?)来查看它正在使用的块大小和块数,但它在两者上都返回 -1。 (为 windows 64 位编译)

难道没有办法在 gfortran 中扩大文件的写入缓冲区吗? linux编译会不会和windows编译不一样?

我真的很想留在 fortran,但作为一种绝望的措施,难道没有办法通过添加一些 c 例程来做到这一点吗?

谢谢!

【问题讨论】:

  • 你是在做格式化输出还是非格式化输出?
  • 缓冲 IO 由环境变量 GFORTRAN_UNBUFFERED_ALL=n 控制。我记得在某处读过,速度与缓冲区大小无关,而是与缓冲区大小有关。 C 变体在编写后不会刷新并且运行速度更快。
  • 谢谢! IanH 我不确定它是什么,抱歉,这里是菜鸟。它还没有使用格式。如果你的意思是 M.S.B.问,它是人类可读的。杯子,我去说明书上查一下,谢谢!特别是如果 gcc for windows (TDM64) 使用该变量。没有等效的命令行选项? “c 变体”是指如果它是用 c 编写的,对吧?

标签: file-io fortran fortran90 gfortran fortran95


【解决方案1】:

IanH 问题是关键。未格式化的 IO 比格式化的要快得多。从 base 2 到 base 10 的转换非常占用 CPU。如果您不需要人类可读的值,请使用未格式化的 IO。如果您希望能够读取其他语言的值,请使用access='stream'

另一种方法是添加您自己的缓冲。将 write 语句替换为对子例程的调用。让该子例程存储值并仅在收到 M 值时写入。您还必须对子例程进行“刷新”调用,以使其写入最后的值,如果它们小于 M。

如果 gcc C 在 IO 上更快,您可以将 Fortran 和 C 与 Fortran 的 ISO_C_Binding 混合使用:https://stackoverflow.com/questions/tagged/fortran-iso-c-binding。在 gfortran 手册的“混合语言编程”下有使用 ISO C Binding 的示例。

【讨论】:

  • 它是人类可读的,但在编写时不使用“格式”。但这是一种选择。我曾考虑过我自己的缓冲区,但还不想使用那个 jsut。谢谢!我会读 c 绑定的东西!
  • 如果它是人类可读的,那么将基数 2 转换为基数 10 会产生高开销。对于未格式化的 IO,请在 open 语句中使用 form='unformatted' 并简单地使用 write (LUN) ...
【解决方案2】:

如果您每 n 个时间步花费 90% 的运行时间来编写坐标/变量,那么显而易见的快速解决方法是每隔 n/100 个时间步写入数据。但我相信你自己已经想到了。

但是是的,gfortran 有一个固定的 8k 缓冲区,其大小无法更改,除非修改 libgfortran 源并重新构建它。缓冲的原因是为了分摊系统调用开销; Linux 上的(简单的)测试表明 8k 就足够了,而且超过了 8k 就进入了收益递减领域。话虽如此,如果您有一些确凿的说法,即更大的缓冲区对某些 I/O 模式和/或操作系统有用,那么没有理由在未来的版本中不能将缓冲区做得更大。

至于您的性能问题,如前所述,未格式化的 I/O 比格式化的 I/O 快得多。此外,gfortran 具有相当高的每个 IO 语句开销。您可以通过编写数组(或数组部分)而不是单个元素来摊销(这对未格式化的 IO 很重要,对于格式化的 IO 有很多事情要做,但这并没有太大帮助)。

【讨论】:

    【解决方案3】:

    我在想,如果 IO 的成本与模拟的工作量相当甚至更大,那么首先将所有这些数据存储到磁盘可能不是一个好主意。最好在模拟期间直接执行您打算执行的任何处理,而不是保存大量中间数据,然后再将它们读入以进行处理。

    此外,MD 本质上是一个高度可并行化的问题,使用 IO 会严重削弱并行化的效率!我会尽可能避免使用 IO。

    对于单个轨迹,通常您只需要存储每个轨迹的初始条件及其关键统计数据或少量时间值的重要快照。当您需要绘制一个特定的轨迹时,您可以从初始条件或最近的快照重新生成完全相同的轨迹或轨迹部分,并且与从磁盘读取它的成本相似。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-16
      • 2015-10-26
      • 1970-01-01
      • 1970-01-01
      • 2012-02-06
      • 2016-02-01
      • 2011-12-24
      相关资源
      最近更新 更多