現在、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 には、それほど美しいルーチンはありませんが、いくつかの非常に便利な関数がまだ存在します。WHERE
orを使用して配列をマスクすると、COUNT
一部MERGE
の操作を効果的に処理するのに役立ちます。
- ただし、マトリックスが 1M エントリを超えると、非常に遅くなります。その場合、順次検索と置換を行っても、マスクを作成したり、where を使用したりするよりも高速です。どうしてそれが可能でしょうか?それらはマルチスレッド化されていませんか?
お待ちいただきありがとうございます。すべての提案は大歓迎です!!