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

use*_*964 2 fortran declaration fortran77 intel-fortran

这个fortran代码最初是用Fortran 77格式编写的(我将在稍后展示).在我得到它之后,我通过转换工具将其更改为f90自由格式.使用intel fortran编译器 ifort,编译和运行与以前一样好.

然后我想做得更多,我想改造非标准的,过时的数据类型声明F77的风格,如:real*8,complex*16等到F90的标准real(8),complex(16).

但我发现了一件令人难以置信的事情.我只是将一个"复杂*16"改为"复杂(16)",然后运行时间从10秒增加到2分钟.怎么会这样!!??有人可以在fortran中解释这种异常行为吗?


以下是详细信息

源文件可以下载 源代码下载链接1源代码下载链接2

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

ifort -w test-16.f90
Run Code Online (Sandbox Code Playgroud)

并运行

./a.out
Run Code Online (Sandbox Code Playgroud)

它将在大约10秒内完成(取决于您的计算机).

现在,我们做了一个小改动.转到第734行,此行显示

  Complex *16 ch, clamda, czero, cspw, com, phase, ctemp
Run Code Online (Sandbox Code Playgroud)

它是f77过时的风格,所以改成f90标准

  Complex(16) ch, clamda, czero, cspw, com, phase, ctemp
Run Code Online (Sandbox Code Playgroud)

并以相同的方式编译,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_'
Run Code Online (Sandbox Code Playgroud)

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

  aimag(ctemp) = dimag(ctemp)
Run Code Online (Sandbox Code Playgroud)

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

因此在删除第744行后,编译就可以了.但是我之前说的运行时间增加到超过2分钟.这真是难以置信,这里有什么不对?

Ian*_*ush 10

噢亲爱的.类型值与变量占用的字节数不同.在大多数(但不是全部)编译器中,复杂(16)是四倍精度(在支持的情况下),这就是为什么你的运行时间通过屋顶.请了解有关价值的信息,例如

Fortran 90种参数

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

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

  • @ user15964你不应该把数字硬编码为你的类型,例如`complex(8)`或`complex(16)`,因为它们对于不同的编译器来说意味着完全不同的东西 - 它们不是*标准化的.如果要以可移植的方式指定特定的存储要求,请参阅作为Fortran 2008标准一部分的`iso_fortran_env`中的命名类常量. (2认同)
  • 如果你没有 iso_fortran_env 可用,另一个是通过 Selected_real_kind (和 Selected_Int_kind) (2认同)