【问题标题】:What is _IO_wfile on a gprof output of a fortran code?Fortran 代码的 gprof 输出中的 _IO_wfile 是什么?
【发布时间】:2015-01-30 20:28:31
【问题描述】:

我有一些使用 intel 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 的?我正在尝试优化此代码,但在 google 中没有找到有关此术语的有用信息。

【问题讨论】:

    标签: fortran intel-fortran gprof


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

      loop for a long time
        write something to somewhere
      

      并使用 gprof 对其进行分析。

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

      因此,如果您的程序是这样的,那么您所看到的也就不足为奇了。

      There's a lot more to this issue.

      【讨论】:

        【解决方案3】:

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

        一些可能性是:

        • 尽量减少 I/O 调用(例如,将它们移出循环)
        • 避免重定向和直接读/写文件
        • 检查blocksizebuffercountopen()中的其他I/O相关选项

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

        • 查看ifort 中的流I/O,它更快,并且您可以自己做缓冲之类的事情,以避免多次调用。但是,它可能会引入可移植性问题,因为其他编译器可能还不支持它或以不同的方式执行它。不要在标准输入/输出上执行此操作(可能在 ifort 中有效,但未记录在案,并且不适用于其他编译器)。
        • 使用iso_c_binding 调用C 函数——例如如果要写入标准输出,可以从 libc 调用 puts()。由于它是标准的,因此它甚至更快并且实际上非常便携,事实上,我在每个操作系统上完成的每个编译器(Win32/linux64/sparc solaris)无论如何都需要(并自动链接)libc;但它相当难看,您必须自己处理诸如空终止之类的事情(例如,通过编写包装函数),这会掩盖代码并可能导致错误。
        • 不要在同一个文件中将这些方法与常规 I/O 混合使用!!

        如果您在代码中显式地进行字符串比较,这些最终也会调用strncmp()。字符串操作在 ifort 中也有点慢(尽管远没有 I/O 差),所以如果您要进行 A LOT 比较,直接调用 strncmp() 可能会获得几秒钟的时间,但我建议不要这样做 - 收益不是那么大,而且它再次掩盖了代码。

        【讨论】:

          猜你喜欢
          • 2017-10-09
          • 2011-08-04
          • 1970-01-01
          • 2011-04-03
          • 2010-10-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多