0

私はFortran77で書かれたレガシーコードの大きな部分を持っています。私はそれをコンパイルし、Intel Fortranコンパイラ(バージョン11?)で実行しています。最近、出力ファイルのサイズが2GBに達し、出力がディスクに書き込まれなくなるという問題が発生しました。

これがFortran77標準の一部であるかどうか、または単にコンパイラフラグなどが欠落しているかどうかを確認するために探し回っていますが、問題を示すものは見つかりませんでした。

レガシーコードは数十万行のオーダーであるため、書き込みステートメントを変更することはできません。最悪のシナリオは、数日ごとに出力の前の部分を別のファイルに切り捨てることですが、これを行う必要がないことをお勧めします。

4

1 に答える 1

3

この種の動作の最も可能性の高い理由は、使用中のメモリモデルです。64ビットモードには、使用されるアドレッシングモードによって区別される3つのメモリモデルがあります。

  • smallモデルRIP関連のアドレス指定は、関数の呼び出しからデータへのアクセスまで、すべてに使用されます。RIPはx64(の64ビット拡張子EIP)の64ビット命令ポインタレジスタですが、相対アドレスは符号付き32ビット数のみにすることができます(完全な符号付き整数範囲の使用を妨げるいくつかの制限があります)。したがって、結合されたコード+静的データサイズは約2GiBに制限されます。
  • mediumモデル-プログラムコードは2GiBに制限されているため、RIP関連する関数呼び出しですが、データシンボルは2つのタイプに分割されます。スモールデータシンボルは、最初の2 GiBのコードとRIP一致するものであり、スモールモデルと同じ相対的な方法を使用してアドレス指定されます。大きなデータシンボルは、レジスタにロードされたシンボルの絶対アドレスを使用したレジスタアドレス指定を使用してアクセスされます。これは低速ですが、アドレス指定可能なメモリに制限はありません。
  • largeモデル-すべてのシンボルは、絶対アドレス指定を使用してアクセスされます。コードやデータサイズに制限はありません。

含まれているx64をターゲットにできるほとんどのコンパイラは、使用されるメモリモデルを制御できるオプションをifort受け入れます。--mcmodel=modelデフォルトのモデルはですsmall。オブジェクトファイルのサイズは、初期化された静的データが大量にあることを意味します。おそらく、非常に大きな初期化された配列(thinkDATAまたはBLOCK DATAステートメント)または多数の小さな配列(100万のコードステートメントでも2 GiBの命令コードが生成されるとは思えません) 。大きなオブジェクトファイルサイズでコンパイルする--mcmodel=medium--mcmodel=large、問題を解決する必要があります。

異なるメモリモデルを使用するオブジェクトコードをリンクすることは災害のレシピであることに注意してください。アプリケーション全体を同じメモリモデルでコンパイルする必要があります。

于 2013-01-05T14:55:41.020 に答える