fortran代码gprof输出上的IO文件是什么?

fortran代码gprof输出上的IO文件是什么?,fortran,intel-fortran,gprof,Fortran,Intel Fortran,Gprof,我有一些用英特尔fortran编译器ifort编译的fortran代码。当我使用gprof进行概要文件测试时,我发现大部分时间都用于IO操作,我认为可以找到文件的结尾,但我找不到更多关于这方面的文档: index % time self children called name <spontaneous> [1] 20.6 0.07 0.00

我有一些用英特尔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]
-----------------------------------------------
索引%time自身子项调用名称
[1] 20.6 0.07 0.00_IO_wfile_seekoff[1]
-----------------------------------------------
[2] 20.6 0.07 0.00 sforcepf_u2[2]
-----------------------------------------------
[3] 20.6 0.02 0.05_IO_wfile_底流[3]
0.01 0.04 258716/258717 strncmp[4]
-----------------------------------------------
0.00 0.00 1/258717默认值分配[15]
0.01 0.04 258716/258717文件下溢[3]
[4] 14.7 0.01 0.04 258717 strncmp[4]
0.04 0.00 3104592/3109256街[5]
-----------------------------------------------
0.00 0.00 4664/3109256 u strcmp_usse42[14]
0.04 0.00 3104592/3109256 strncmp[4]
[5] 11.8 0.04 0.00 3109256街[5]
-----------------------------------------------

所以,问题是,这个IO是特定于Linux、iPort还是fortran的?我正在尝试优化这段代码,但在谷歌上找不到关于这一术语的有用信息。

您可以编写Fortran语句。英特尔Fortran编译器将这些语句转换为汇编程序,包括对系统函数的调用。例如,
strncmp
是一个ISO C标准函数,用于比较字符串的各个部分。因此,看起来您正在编写Fortran语句来比较字符串,“英特尔Fortran编译器”正在调用现有函数来实现比较。其中一些系统功能本身(部分)将通过调用平台上提供的更基本的功能来实现

gprof
向您展示了它在编译产品中找到的函数调用。您看到的大部分内容都是特定于Linux I/O的——在Windows机器上,I/O将使用具有不同名称的类似函数。您看到的某些内容可能特定于英特尔编译器,所有英特尔编译器在某些操作中使用相同的(英特尔创建的)函数,并且该函数使用特定于平台的低级函数


除非您准备重写这些低级函数,并冒着在使用相同函数的其他程序中破坏它们的风险,否则您可以进行的唯一优化就是减少调用它们的频率。例如,如果您有理由认为读取超过文件结尾是一项昂贵的I/O操作,并且如果您的程序策略是读取文件直到读取超过结尾,然后处理出现的错误,那么您可能需要实施更高级的程序策略。这将比重新编写处理策略后果的低级I/O例程更容易。

假设您使用任何语言编写以下内容

loop for a long time
  write something to somewhere
并使用gprof对其进行配置

gprof在IO或任何其他阻塞状态期间暂停采样。 这个程序所做的很少,但在它所花费的周期中,大多数都是在进入和退出内置的库例程,这些例程启动IO并等待IO完成

所以,如果你的程序是这样的,那么你看到的就是这样也就不足为奇了


看起来您正在看到Fortran I/O操作。格式化的I/O在
ifort
中相当慢。如果使用标准输入/标准输出重定向,情况会变得更糟;更糟糕的是管道——英特尔文档特别警告不要这样做
gfortran
没有那么糟糕,但仍然相当缓慢

有些可能性是:

  • 尽量少做I/O调用(例如,将它们移出循环)
  • 避免直接重定向和读/写文件
  • open()
如果这还不够,并且I/O是您的主要瓶颈,您可以考虑:

  • 查看
    ifort
    中的流I/O,速度更快,您可以自己进行缓冲等操作,以避免多次调用。但是,它可能会带来可移植性问题,因为其他编译器可能还不支持它,或者采用不同的方式。不要在标准输入/输出上执行此操作(可能在ifort中工作,但它没有文档记录,并且不能与其他编译器一起工作)
  • 使用
    iso_c_binding
    调用c函数——例如,如果您正在写入标准输出,则可以从libc调用
    put()
    。因为它是标准的,所以速度更快,而且实际上相当可移植,事实上,我在每个操作系统(Win32/linux64/sparc solaris)上做过的每个编译器都需要(并自动链接)libc;但它相当丑陋,您必须自己处理空终止之类的事情(例如,通过编写包装器函数),这会模糊代码并导致bug
  • 不要将这些方法与同一文件上的常规I/O混合使用
如果您在代码中显式地进行字符串比较,那么它们最终也会调用
strncmp()
。ifort中的字符串操作也有点慢(虽然远没有I/O那么糟糕),因此,如果要进行大量比较,直接调用
strncmp()
可能会获得几秒钟的时间,但我建议不要这样做,因为增益没有那么大,而且会使代码变得模糊