在具有多个分配级别的Fortran中使用锯齿状数组是否有任何问题? [英] Are there any problems with using jagged-arrays in Fortran with multiple levels of allocation?

查看:106
本文介绍了在具有多个分配级别的Fortran中使用锯齿状数组是否有任何问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Fortran代码中,我想使用具有多个分配级别的锯齿状数组。我的意思的示例代码是

In my Fortran code, I want to use jagged arrays with multiple levels of allocation. An example code of what I mean is

module nonsquare_matrix_mod
implicit none

   type :: nonsquare_matrix 
      integer :: d
      real*8, dimension(:), allocatable :: vector
   end type nonsquare_matrix

   type(nonsquare_matrix),dimension(:),allocatable :: mymatrix

end module nonsquare_matrix_mod

program nonsquare_matrix_test
   use nonsquare_matrix_mod
   implicit none

integer, parameter :: max_size=50
integer :: i

allocate(mymatrix(max_size))
do i=1,max_size
    allocate(mymatrix(i) % vector(i))
end do

print *, "allocated"


end program

我想实现此编程策略以节省内存。我知道此示例中保存的内存不会太大,但是对于我的实际项目,我正在处理更大的数据结构。我想知道这种编程实践是否存在任何危险,例如数据不能连续存储或更容易发生内存泄漏。还是这是一种没有很多缺点的节省内存的有用方法?谢谢。

I want to implement this programming strategy in order to conserve memory. I know the memory saved in this example isn't too large, but for my actual project, I'm working with much larger data structures. I was wondering if there are any dangers with this programming practice, such as data not being stored contiguously or being more prone to memory leaks. Or is this a useful way of saving memory without many drawbacks? Thanks.

推荐答案

由于仅使用可分配数组,因此不会有任何内存泄漏,使用指针。锯齿状的数组是否是解决问题的合理方法,在很大程度上取决于数据的结构。需要注意的几点:

Since you are using allocatable arrays only, you won't have any memory leak as it could be the case when using pointers. Whether the jagged array is a reasonable solution for your problem depends very much on the structure of your data. A few points to be noted:


  • 实际上,您的数组不会是连续的。这具有多种含义,例如访问后续行时更糟糕的缓存行为。

  • Your array won't be contigous, indeed. That has several implication, like worse caching behaviour, when you are accessing subsequent lines.

您必须通过 allocate 分别。如果它经常发生(例如在循环内),那可能是个问题,因为分配是一个相当缓慢的操作。

You have to allocate every line via allocate individually. If it happens very often (e.g. inside a loop), that could be a problem, as allocation is a rather "slow" operation.

如果您的数组的大小确实有很大不同(并且您没有太多行),您可以节省一些内存。

If the lines in your array are really very different in size (and you do not have too many lines), you may save some considerable amount of memory.

如果行的长度是在创建时设置的,并且此后未更改(并且您很好地猜测了整个数组中将有多少个元素),则可以分配一个大缓冲区数组,在其中放置行,以及一个索引数组,其中包含该行的第一个元素在缓冲区数组中的位置:

If the length of the lines is set at the time of their creation and not changed afterwards (and you have a good guess of maximally how much elements you will have in your entire array), you could allocate a large buffer array, where you put in the lines, and an index array which contains the position of the first element of that line in the buffer array:

 program nonsquare_matrix_test
  implicit none

  integer, parameter :: dp = kind(1.0d0)
  integer, parameter :: maxlines = 50
  integer, parameter :: maxelements = 5000
  real(dp), allocatable :: buffer(:)
  integer, allocatable :: rowindex(:)
  integer :: ii

  allocate(buffer(maxelements))
  allocate(rowindex(maxlines + 1))
  rowindex(1) = 1
  do ii = 1, maxlines
    rowindex(ii + 1)  = rowindex(ii) + ii
  end do
  ! ...  
  ! Omitting the part which fills up the array
  ! ...
  ! Accessing a given line (e.g. line 5)
  print *, "Content of line 5:"
  print *, buffer(rowindex(5):rowindex(6)-1)

end program nonsquare_matrix_test

这篇关于在具有多个分配级别的Fortran中使用锯齿状数组是否有任何问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆