我有一大段用Fortran 77编写的遗留代码。我正在编译它并使用英特尔Fortran编译器(版本11?)运行它。我最近遇到了一个问题,输出文件的大小只有2GB,并且输出停止写入磁盘。
我一直在寻找,看看这是否是Fortran 77标准的一部分,或者我是否只是缺少编译器标志或其他东西,但没有发现任何指向我的问题。
更改write语句不是一种选择,因为遗留代码大约有几十万行。最糟糕的情况是,每隔几天我就进入并将输出的早期部分截断为不同的文件,但我希望我不必这样做。
答案 0 :(得分:3)
这种行为最可能的原因是使用的内存模型。在64位模式下,有三种存储器模型,区别在于使用的寻址模式:
small
模型 - RIP
- 相关寻址用于从调用函数到访问数据的所有内容。 RIP
是x64的64位指令指针寄存器(EIP
的64位扩展名),但相对地址只能是带符号的32位数(并且有一些限制可以防止使用完整的有符号整数范围),因此组合代码+静态数据大小限制在大约2 GiB。medium
模型 - 程序代码限制为2 GiB,因此RIP
- 相关函数调用,但数据符号分为两种类型。小数据符号是与前2 GiB中的代码一起使用的符号,它们使用与小模型中相同的RIP
相对方法进行寻址。使用寄存器寻址访问大数据符号,加载到寄存器中的符号的绝对地址较慢,但可寻址存储器没有限制。large
模型 - 使用绝对寻址访问所有符号。对代码或数据大小没有限制。大多数可以定位x64,ifort
的编译器接受--mcmodel=model
选项,允许用户控制所使用的内存模型。默认模型为small
。目标文件的大小意味着有大量初始化的静态数据,可能是一些非常大的初始化数组(想想DATA
或BLOCK DATA
语句)或许多较小的数组(我怀疑甚至100万代码语句将生成2 GiB的指令代码)。使用--mcmodel=medium
或--mcmodel=large
进行编译可以解决大对象文件大小的问题。
请注意,将使用不同内存模型的目标代码链接在一起会导致灾难 - 整个应用程序应使用相同的内存模型进行编译。