首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用数组组件设计派生类型

使用数组组件设计派生类型
EN

Stack Overflow用户
提问于 2016-12-10 04:03:15
回答 1查看 734关注 0票数 3

在设计派生类型时,我很难找到任何具体的信息。我认为讨论这个问题的最好方法是通过几个选项。我已经用派生类型的不同应用程序组成了一些代码部分。我更喜欢对npartsindexrefs使用动态数组。我省略了实际使用该结构的代码部分(没有任何部分,因为是我编出来的),但是会显示一个示例,并且在例程中,我打算至少使用结构中的所有值一次。

选项A:在派生类型中使用静态数组。缺点是我必须在编译时猜测数组大小。

代码语言:javascript
复制
! 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:在派生类型中使用动态数组。

代码语言:javascript
复制
! 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成为数组。注意,尽管在这个版本中,我们有一堆未使用的内存。例如,npartsindexassembly(packs,packs,nboxes)开始就需要内存packs-times。

代码语言:javascript
复制
! 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的另一个置换。

问题:

  1. 为显示的do循环示例设计派生类型的正确/预期方法是哪个版本?考虑到我喜欢动态数组功能,哪个版本是最优化的?
  2. 可能和上面的事有关。如何分配和访问内存?SEQUENCE的使用是否值得?我认为分配的数组不会按顺序出现。这不是指选项C是最好的,因为assembly的每个部分都比较小吗?
  3. 我是否应该将这个派生类型拆分成多个派生类型,或者完全摆脱它,只停留在变量上?我将在多个例程上使用这种派生类型,并将其放在一个模块中。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-10 06:34:12

  1. 您希望以变化最快的索引作为最内部的循环。变化最快的索引是多维数组中的第一个.因此,备选方案B接近这一目标。尽管您可能希望更改参考文献中维度的顺序。
  2. 由索引(i,j)访问的二维形状数组(m,n)的内存布局是通过以下顺序给出的:k = i+m*(j-1),其中k表示内存中的一维索引。派生的数据类型将包含对分配内存的引用,所包含的可分配对象的实际内存可能分散在内存中,但每个可分配数组本身是连续的。因此,在您的选项B中,assembly将是一个连续数组,包含对可分配数组的引用。每个npartsindexrefs本身都是连续数组,但它们可能位于任意位置,在一个程序集元素中或在不同的组装元素之间没有特定的关系。在这里使用SEQUENCE没有任何意义,它迫使编译器按顺序将派生数据类型的元素放入内存中,这样您就可以声明并禁止它根据自己的意愿重新排列数据类型的组件,这可能会限制性能。我怀疑,在你的例子中它会有很大的效果,但是当它不需要的时候,你应该离开它。
  3. 不,在我看来,选项B看起来非常合理(除了sequence)。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41072040

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档