派生型の設計に関する具体的な情報を見つけるのに苦労しました。これについて議論する最善の方法は、いくつかのオプションを使用することだと思います。派生型のさまざまなアプリケーションを使用して、コードのいくつかのセクションを作成しました。nparts
、index
、およびには動的配列を使用したいと思いますrefs
。構造体を実際に使用するコードのセクションは省略しましたが (私が作成したものなのでありません)、例を示し、ルーチンで構造体のすべての値を少なくとも 1 回は使用するつもりです。
オプション A:派生型で静的配列を使用します。欠点は、コンパイル時に配列のサイズを推測する必要があることです。
! Known before compile time.
nboxes = 5000
max_parts = 2000
packs = 10
Type Boxes
Sequence
Integer :: location, date
Integer, Dimension(0:packs) :: nparts
Integer, Dimension(max_parts,packs) :: index
Real(Kind=8), Dimension(packs,packs) :: refs
End Type Boxes
type(boxes), dimension(:), allocatable :: assembly
allocate(assembly(nboxes))
! Perform some operations on assembly...
do i = 1,nboxes
do j = 1,packs
do k = j,packs
example = assembly(i)%nparts(k) - assembly(i)%nparts(j)
.
.
do m = 1,max_parts
example = assembly(i)%index(m,j) + assembly(i)%refs(k,j) * assembly(i)%nparts(j)
.
.
end do
end do
end do
end do
オプション B:派生型で動的配列を使用します。
! Defined during execution. Much better.
nboxes = 5000
max_parts = 2000
packs = 10
Type Boxes
Sequence
Integer :: location, date
Integer, Dimension(:), Allocatable :: nparts
Integer, Dimension(:,:), Allocatable :: index
Real(Kind=8), Dimension(:,:), Allocatable :: refs
End Type Boxes
type(boxes), dimension(:), allocatable :: assembly
allocate(assembly(nboxes))
do i = 1,nboxes
allocate(assembly(i)%nparts(0:packs))
allocate(assembly(i)%index(max_parts,packs))
allocate(assembly(i)%refs(packs,packs))
end do
! Perform some operations on assembly...
do i = 1,nboxes
do j = 1,packs
do k = j,packs
example = assembly(i)%nparts(k) - assembly(i)%nparts(j)
.
.
do m = 1,max_parts
example = assembly(i)%index(m,j) + assembly(i)%refs(k,j) * assembly(i)%nparts(j)
.
.
end do
end do
end do
end do
オプション C:派生型で使用される動的配列の数を最小限に抑え、強制的assembly
に配列にします。ただし、このバージョンでは未使用のメモリが大量にあることに注意してください。たとえば、nparts
から の時間のindex
メモリが必要です。packs
assembly(packs,packs,nboxes)
! Defined during execution. Much better.
nboxes = 5000
max_parts = 2000
packs = 10
Type Boxes
Sequence
Integer :: location, date, nparts, index
Real(Kind=8) :: refs
Integer, Dimension(:), Allocatable :: index
End Type Boxes
type(boxes), dimension(:,:,:), allocatable :: assembly
allocate(assembly(packs,packs,nboxes))
do i = 1,nboxes
do j = 1,packs
do k = 1,packs
allocate(assembly(k,j,i)%index(max_parts))
end do
end do
end do
! Perform some operations on assembly...
do i = 1,nboxes
do j = 1,packs
do k = j,packs
example = assembly(k,j,i)%nparts - assembly(k,j,i)%nparts
.
do m = 1,max_parts
example = assembly(k,j,i)%index(m) + assembly(k,j,i)%refs * assembly(k,j,i)%nparts
.
.
end do
end do
end do
end do
オプション D:オプション C の別の順列。
質問:
do
示されているループ例の派生型を設計する正しい/予想される方法は、どのバージョンですか? 動的配列機能が必要な場合、どのバージョンが最も最適化されていますか?- 上記に関連しているのかもしれません。メモリはどのように割り当てられ、アクセスされますか? の使用は
SEQUENCE
価値がありますか? とにかく、割り当てられた配列は順番に表示されないと思います。assembly
の各セクションが小さいため、これはオプション C が最適であることを示しているのではないでしょうか? - この派生型を複数の派生型に分割するか、完全に削除して変数に固執する必要がありますか? この派生型を複数のルーチンで使用し、モジュールに配置します。