什么是对的Fortran代码一个gprof的输出_IO_wfile?(What is _IO_wfi

2019-09-16 11:19发布

我有英特尔Fortran编译器ifort整理了一些Fortran代码。 当我使用gprof配置文件测试,我得到的大部分时间在IO操作时,我想找到文件的末尾,但我无法找到任何这更多的文档:

index % time    self  children    called     name
                                                 <spontaneous>
[1]     20.6    0.07    0.00                 _IO_wfile_seekoff [1]
-----------------------------------------------
                                                 <spontaneous>
[2]     20.6    0.07    0.00                 sforcepf_ [2]
-----------------------------------------------
                                                 <spontaneous>
[3]     20.6    0.02    0.05                 _IO_wfile_underflow [3]
                0.01    0.04  258716/258717      strncmp [4]
-----------------------------------------------
                0.00    0.00       1/258717      _IO_wdefault_doallocate [15]
                0.01    0.04  258716/258717      _IO_wfile_underflow [3]
[4]     14.7    0.01    0.04  258717         strncmp [4]
                0.04    0.00 3104592/3109256     strerror_r [5]
-----------------------------------------------
                0.00    0.00    4664/3109256     __strcmp_sse42 [14]
                0.04    0.00 3104592/3109256     strncmp [4]
[5]     11.8    0.04    0.00 3109256         strerror_r [5]
-----------------------------------------------

所以,问题是,这是IO具体到Linux,或ifort,或FORTRAN? 我试图优化这个代码,并发现这个术语在谷歌没有任何有用的信息。

Answer 1:

你写Fortran语句。 英特尔Fortran编译转换的语句转换为汇编包括调用系统功能。 例如, strncmp是ISO C标准函数比较字符串的部分。 因此,它看起来就像你正在编写Fortran语句比较字符串,以及英特尔Fortran编译器是调用现有的功能,实现了比较。 其中的一些系统功能将自己所提供的平台上更根本的函数的调用来实现(部分)。

gprof是显示你先找到你的编译的产品中提到的函数的调用。 大多数时候,你看到的是具体到Linux I / O - 在Windows机器上的I / O将使用类似的职能,不同的名称。 这可能是一些你所看到的是特定于英特尔编译器,所有的英特尔编译器使用相同(英特尔创建的)功能对于一些操作,并且该功能使用特定于平台的较低级别的功能。

除非你准备重写这些低级别的功能,并采取你会使用相同的功能拧起来为其他程序的风险,那么几乎可以使唯一的优化是不经常给他们打电话。 例如,如果你有理由认为,阅读过去的文件的末尾是一个昂贵的I / O操作,而如果你的程序的策略是,直到你读过去的结束,然后与出现错误处理读取文件,那么你可能要实现卓越的方案战略。 这将是比重新编写其处理你的战略后果的低级别的I / O例程更容易。



Answer 2:

假设你写在任何语言以下

loop for a long time
  write something to somewhere

gprof的个人资料吧。

gprof的 IO或任何其他阻塞状态期间暂停采样。 这个程序确实非常少,周期,但它花费的周期,其中大部分都花在进出内置库例程开始IO并等待它完成的。

所以,如果你的程序是这样的,这并不奇怪,这就是你看到的。

还有更多的这个问题很多。



Answer 3:

看起来你看到的Fortran I / O操作。 格式化的I / O是相当缓慢ifort 。 如果使用标准输入/标准输出重定向,它会变得更糟; 并仍与管道更糟 - 英特尔文档特别警惕这样做。 gfortran是几乎没有坏,但仍相当缓慢。

一些可能性:

  • 尝试尽可能少的I / O调用尽可能做到(例如将其移出循环)
  • 避免重定向和读/写文件,而不是直接
  • 检查blocksizebuffercount和其他的I / O相关选项open()

如果这还不够,和I / O是你的主要瓶颈,您可以考虑:

  • 寻找到流的I / O ifort ,它更快,你可以做这样的事情缓冲自己,以避免多次调用。 它可能,但是,引入的可移植性问题,因为其他的编译器可能不支持它仍然还是采取不同的方式。 不要做它的标准输入/输出(可能在ifort工作,但它没有证件,并不会与其他编译器工作)。
  • 使用iso_c_binding调用C函数-例如,如果你正在写到标准输出,你可以调用puts()从libc中。 这是更快,实际上是相当便携,因为它是标准的,而事实上每个OS我做它的(Win32 / LINUX64 / SPARC Solaris)上每编译器要求(并自动链接)的libc无妨; 但它是比较难看的,你要照顾的东西像空终止自己(例如,通过写一个包装函数),这掩盖了代码,并能诱导错误。
  • 与常规的I / O上相同的文件不要混合使用上述任何一种方法!

如果你在你的代码中显式做字符串比较,这些最终会调用strncmp()了。 字符串操作也是ifort有点慢(虽然远不一样糟糕I / O),所以如果你正在做的比较了很多 ,你可以通过调用获得几秒钟strncmp()直接,但我会建议针对 - 增益没有那么大,并且再次,它掩盖了代码。



文章来源: What is _IO_wfile on a gprof output of a fortran code?