"英特尔Fortran编译器",文件大小较大



我有一大块用Fortran 77编写的遗留代码。我正在用"英特尔Fortran编译器"(版本11?)编译并运行它。我最近遇到了一个问题,输出文件的大小不到2GB,并且输出停止写入磁盘。

我四处寻找,看看这是否是Fortran 77标准的一部分,或者我是否只是缺少编译器标志或其他什么,但没有找到任何指向我问题的东西。

更改write语句不是一种选择,因为遗留代码大约有几十万行。最糟糕的情况是,每隔几天我就会进入并将输出的早期部分截断到不同的文件中,但我希望不必这样做。

这种行为最可能的原因是所使用的内存模型。在64位模式中,有三种存储器模型,通过使用的寻址模式来区分:

  • small模型-与RIP相关的寻址用于从调用函数到访问数据的所有操作。RIP是x64的64位指令指针寄存器(EIP的64位扩展),但相对地址只能是一个有符号的32位数字(并且有一些限制阻止使用完整的有符号整数范围),因此组合代码+静态数据大小限制为约2GiB
  • medium模型程序代码限制为2GiB,因此RIP相关的函数调用,但数据符号分为两种类型。小数据符号是那些与前2GiB中的代码配合在一起的符号,它们使用与小模型中相同的RIP相对方法进行寻址。使用寄存器寻址访问大数据符号,将符号的绝对地址加载到寄存器中,这较慢,但对可寻址存储器没有限制
  • large模型-使用绝对寻址访问所有符号。代码或数据大小没有限制

大多数可以针对x64(包括ifort)的编译器都接受--mcmodel=model选项,该选项允许控制所使用的内存模型。默认型号为small。对象文件的大小意味着有大量初始化的静态数据,可能是一些非常大的初始化数组(想想DATABLOCK DATA语句)或许多更小的数组(我怀疑即使是100万个代码语句也会生成2GIB的指令代码)。使用--mcmodel=medium--mcmodel=large编译应该可以解决对象文件大小较大的问题。

请注意,将使用不同内存模型的对象代码链接在一起会导致灾难——整个应用程序应该使用相同的内存模型进行编译。

最新更新