0

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

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

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

4

1 回答 1

3

这种行为最可能的原因是使用的内存模型。在 64 位模式中,存在三种内存模型,以使用的寻址模式区分:

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

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

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

于 2013-01-05T14:55:41.020 回答