为什么将 "complex*16" 更改为 "complex(16)" 导致运行时间在 fortran 中不合理地增加?

why change "complex*16" to "complex(16)" cause the runtime increased unreasonably in fortran?

这段fortran代码最初是用Fortran 77格式写的(稍后会展示)。拿到后,我通过转换工具将其转换为f90自由格式。使用 intel fortran 编译器 ifort,编译和 运行ning 和以前一样好。

然后我想做更多,我想将非标准的,过时的数据类型声明f77风格如:real*8complex*16等转换为f90标准real(8)complex(16).

但是我发现了一件不可思议的事情。 我刚把一个"complex*16"改成"complex(16)",然后运行宁时间从10秒增加到2分钟。怎么可能!!?? 谁能用 Fortran 语言解释这种异常行为?


详情如下

源文件可以下载 source code download link 1 or souce code download link 2

首先,您可以使用 ifort 编译 f90 文件,忽略所有警告

ifort -w test-16.f90

和运行

./a.out

大约 10 秒内完成(取决于您的计算机)。

现在,我们做一个小改动。转到第 734 行,这一行显示为

  Complex *16 ch, clamda, czero, cspw, com, phase, ctemp

是f77的过时款式,改成f90标准

  Complex(16) ch, clamda, czero, cspw, com, phase, ctemp

同理编译,ifort会报错

/tmp/ifortvaXMFi.o: In function `fite4_':
test-(16).f90:(.text+0x9ecf): undefined reference to `dimag_'
test-(16).f90:(.text+0xa354): undefined reference to `dimag_'

不知道为什么,我发现第744行有一句很可疑的句子

  aimag(ctemp) = dimag(ctemp)

我真的不明白什么意思。但是整个代码只有三个地方出现了"ctemp"。很明显,这条线是多余的。所以我们可以安全地删除它。

所以删除744行后,编译就OK了。但是之前说的运行ning时间增加到2分钟多。真是难以置信,这是怎么了?

哦,亲爱的。种类值与变量占用的字节数不同。在大多数(但不是全部)编译器中,complex(16) 是四倍精度(在支持的情况下),这就是为什么您的 运行 时间过长的原因。请了解 kind 值,例如参见

Fortran 90 kind parameter

开始,然后了解对于复杂变量,种类值与构成它的实际值的种类相同。

我就不多说了,老实说,如果有人发布了一个相对较长的程序,然后告诉我在编译过程中忽略警告,然后解决他们的问题,我不觉得倾向于投入更多精力。修复警告,将程序减少到最多几十行,然后我,我怀疑大多数其他人,会更仔细地看。