在设计派生类型时,我很难找到任何具体的信息。我认为讨论这个问题的最好方法是通过几个选项。我已经用派生类型的不同应用程序组成了一些代码部分。我更喜欢对nparts、index和refs使用动态数组。我省略了实际使用该结构的代码部分(没有任何部分,因为是我编出来的),但是会显示一个示例,并且在例程中,我打算至少使用结构中的所有值一次。
选项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从assembly(packs,packs,nboxes)开始就需要内存packs-times。
! 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的使用是否值得?我认为分配的数组不会按顺序出现。这不是指选项C是最好的,因为assembly的每个部分都比较小吗?发布于 2016-12-10 06:34:12
k = i+m*(j-1),其中k表示内存中的一维索引。派生的数据类型将包含对分配内存的引用,所包含的可分配对象的实际内存可能分散在内存中,但每个可分配数组本身是连续的。因此,在您的选项B中,assembly将是一个连续数组,包含对可分配数组的引用。每个nparts、index和refs本身都是连续数组,但它们可能位于任意位置,在一个程序集元素中或在不同的组装元素之间没有特定的关系。在这里使用SEQUENCE没有任何意义,它迫使编译器按顺序将派生数据类型的元素放入内存中,这样您就可以声明并禁止它根据自己的意愿重新排列数据类型的组件,这可能会限制性能。我怀疑,在你的例子中它会有很大的效果,但是当它不需要的时候,你应该离开它。sequence)。https://stackoverflow.com/questions/41072040
复制相似问题