0

現在、Fortran 95 で数値シミュレーション用のコードを作成しています。私のプラットフォームは Windows で、Intel Fortran コンパイラを使用して MSVC 環境を利用しています。このコードは、この分野の多くのコードと同様に、解決される連立方程式を作成します。数値的には、これは正方行列と既知の値のベクトルを格納して発生します。ここで、メモリを最適化するために、圧縮されたスパース行形式 (CSR) などの便利な形式で行列が格納されるため、ゼロ値は格納されません。

この簡単な紹介を考えると、ここに私の疑問があります。コンパイル時には配列の次元がわからないので、次のように宣言します。

REAL, DIMENSION(:), ALLOCATABLE :: myArray

そして、そのようなベクトルの次元を取得したら、次を呼び出します

ALLOCATE(myArray(N)) where N is the number of elements that I want to allocate
  • それでも、値が格納されていないため、メモリは空ですが、スタック オーバーフローを回避するためにメモリ チェックが行われます。そうですか?

ここで、値を入力すると、占有スペースが増加します。1D ベクトルと多次元配列の両方の Fortran 配列の構造は、値の数に相当するスペースを列順に埋めることです。次元が 1000x1000 の 2D 配列がある場合、それは列番号順に並べられた 1M の「連続したボックス」に格納されます (最初に最初の列が格納され、次に 2 番目の列が格納されます)。

  • これが当てはまる場合、データの構造は同じです。特定の値へのアクセス時間は、多次元ベクトルと 1D ベクトルの唯一の違いですか?

  • それでは、コマンドRESHAPEはプログラムが配列を「見る」方法だけを変更していますか?

目的に必要な配列は、各サブルーチン/関数が共有するモジュールで定義されています。特に、サブルーチンはそれを割り当てて埋めます。メイン プログラムに戻ると、それに関する統計をユーザーに表示するので、問題はありません。たとえば、4 億 REAL*4 の値を割り当て、約 1.5 GB のメモリを使用したとします。

  • ただし、別のサブルーチンに入ると、プログラムはforrtl: severe(170): Program Exception - Stack Overflow. メモリが不足しました。しかし、マトリックスが既に割り当てられていて、それ以上何も割り当てていない場合はどうすればよいでしょうか? サブルーチンは同じモジュールを使用するため、変数は既に宣言されています。私のRAMにはまだ約1.3GBの空き容量があります。ストップはサブルーチンの最初の行にあります。

  • サブルーチン (および関数) はデータを 2 倍にしていますか? その場合、Fortran は変数のアドレスを渡し、コピーを避けて値を直接処理すると考えていました。

最後に、皆さんと同じように、私は C++ で vector::push_back などの STD ライブラリ関数を楽しんでいました。Fortran には、それほど美しいルーチンはありませんが、いくつかの非常に便利な関数がまだ存在します。WHEREorを使用して配列をマスクすると、COUNT一部MERGEの操作を効果的に処理するのに役立ちます。

  • ただし、マトリックスが 1M エントリを超えると、非常に遅くなります。その場合、順次検索と置換を行っても、マスクを作成したり、where を使用したりするよりも高速です。どうしてそれが可能でしょうか?それらはマルチスレッド化されていませんか?

お待ちいただきありがとうございます。すべての提案は大歓迎です!!

4

1 に答える 1

2

コメントスペースが限られているので、これを回答として投稿します。明らかに、メモリ不足ではなく、スタック スペースが不足しています。Windows のメイン スレッドのスタック サイズはリンク時に固定され (デフォルトは 1 MiB)、それより大きいスタック割り当てはスタック オーバーフローを引き起こす可能性があります。これは多くの理由で発生する可能性がありますが、主に次の理由があります。

  • 呼び出すサブルーチンが大きなスタック配列 (非ALLOCATABLE配列など) を使用している。
  • 連続していない配列サブセクションをサブルーチンに渡します。たとえばmyArray(1:10:2)、サブルーチンに明示的なインターフェイスがありません。この場合、コンパイラは、渡されるデータの最も可能性の高い一時的なスタック コピーを作成します。これにより、スタック スペースが使い果たされ、例外がトリガーされる可能性があります。

サブルーチンに入ると例外が発生するため(おそらく、すべてのローカル変数のスタックスペースが予約されているプロローグで)、最初のポイントはあなたのケースに関連するものだと思います。プロジェクト設定でヒープ配列を有効にするようインテル Fortran に指示し、それが役立つかどうかを確認することができます (Windows バージョンでヒープ配列がデフォルトで有効になっているかどうかは不明です)。

コードが 1 行も表示されていなければ、問題の原因を推測して解決することは非常に困難です。

于 2013-01-25T17:59:53.310 に答える