fortran代码gprof输出上的IO文件是什么?
我有一些用英特尔fortran编译器ifort编译的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
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中工作,但它没有文档记录,并且不能与其他编译器一起工作)ifort
- 使用
调用c函数——例如,如果您正在写入标准输出,则可以从libc调用iso_c_binding
。因为它是标准的,所以速度更快,而且实际上相当可移植,事实上,我在每个操作系统(Win32/linux64/sparc solaris)上做过的每个编译器都需要(并自动链接)libc;但它相当丑陋,您必须自己处理空终止之类的事情(例如,通过编写包装器函数),这会模糊代码并导致bug李>put()
- 不要将这些方法与同一文件上的常规I/O混合使用李>
strncmp()
。ifort中的字符串操作也有点慢(虽然远没有I/O那么糟糕),因此,如果要进行大量比较,直接调用strncmp()
可能会获得几秒钟的时间,但我建议不要这样做,因为增益没有那么大,而且会使代码变得模糊