gfortran更改/找出写入缓冲区大小

时间:2013-12-31 00:31:26

标签: file-io fortran fortran90 gfortran fortran95

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

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

我甚至试图做一个FSTAT(在打开之后,是吗?)看看它使用的块大小和块数是多少但是它们都返回-1。 (编译为Windows 64位)

有没有办法在gfortran中放大文件的写缓冲区?对于linux而言,它是否会与windows不同?

我真的很想留在Fortran中,但是作为一种绝望的措施是不是有办法通过增加一些c例程来做到这一点?

谢谢!

3 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:1)

如果你花费90%的运行时间每隔n步执行coords / vels,那么显而易见的快速修复就是每次写入数据,比如n / 100次步。但我相信你自己已经想过了。

但是,是的,gfortran有一个固定的8k缓冲区,除了修改libgfortran源并重建它之外,它的大小不能改变。缓冲的原因是分摊系统调用开销; Linux上的(简单化)测试表明,8k就足够了,而且远远超过收益递减区域。话虽如此,如果你有一些证据表明更大的缓冲区对某些I / O模式和/或操作系统有用,那么在将来的版本中没有理由不能将缓冲区扩大。

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

答案 2 :(得分:0)

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

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

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