fortran - Fortran 中的未知大小矩阵

标签 fortran dynamic-memory-allocation

我想将元素添加到一维矩阵 mat,但要遵守下面测试程序中的条件。在 Fortran 2003 中您可以添加元素

mat=[mat,i]

如相关问题Fortran array automatically growing when adding a value中所述。不幸的是,这对于大型矩阵来说非常慢。因此,我尝试通过将矩阵元素写入未格式化文件中并随后读取它们来克服这个问题。事实证明,这比使用 mat=[mat,i] 快得多。例如,对于 n=2000000_ilong,运行时间为 5.1078133666666661 分钟,而如果将矩阵元素存储在文件中,则运行时间将降至 3.5234166666666665E-003 分钟
问题是,对于大矩阵大小,文件 storage.dat 可能有数百 GB... 有什么想法吗?

program test


implicit none

integer, parameter :: ndig=8
integer, parameter :: ilong=selected_int_kind(ndig)
integer (ilong), allocatable :: mat(:)
integer (ilong), parameter :: n=2000000_ilong
integer (ilong) :: i, cn 
logical, parameter :: store=.false.
real(8) :: z, START_CLOCK, STOP_CLOCK


open(1, file='storage.dat',form='unformatted')

call cpu_time(START_CLOCK)

if(store) then 

 cn=0
 do i=1,n
   call random_number(z)
   if (z<0.5d0) then 
     write(1) i
     cn=cn+1
   end if 
 end do


 rewind(1); allocate(mat(cn)); mat=0

 do i=1,cn
  read(1) mat(i)
 end do


else 

 allocate(mat(1)); mat=0
 do i=1,n
   call random_number(z)
   if (z<0.5d0) then 
    mat=[mat,i]
   end if 
 end do



end if




call cpu_time(STOP_CLOCK)
print *, 'run took:', (STOP_CLOCK - START_CLOCK)/60.0d0, 'minutes.'


end program test

最佳答案

如果数据文件有数百 GB,则可能根本没有可用的解决方案,因为无论如何您的阵列都需要如此多的 RAM 内存。也许你犯了一个错误,将数据存储为文本,那么内存大小会稍微小一些,但仍然有几十GB。

当您需要逐一添加元素并且不知道最终大小时,通常所做的就是逐步以几何方式增长数组。这意味着预先分配一个数组的大小为N。当数组已满时,您分配一个大小为 2*N 的新数组。当数组再次满时,将其分配给4*N。等等。要么你完成了,要么你耗尽了你所有的内存。

当然,通常最好事先知道数组的大小,但在某些算法中,您根本没有这些信息。

关于fortran - Fortran 中的未知大小矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75398668/

相关文章:

python-2.7 - 数据交换——Python 和 Fortran

multidimensional-array - 矩阵的 Fortran 转置不适用于非二维数组

arrays - (/值/) 是什么意思? value 是子例程的输入参数

c - 调用 C_F_POINTER 时 Fortran 指针和 Fortran 可分配的区别

gcc - 以非编译器特定的方式更改 Fortran 中的目录

c - 如何在C中的链表中释放不同大小的分配内存

c++ - 使用 C++ 操作符重载 : class with pointer datat members

c++ - 测试内存分配失败的正确行为

c - C函数中的指针到指针;链表

c - malloc 在分配内存时是否预留了更多空间?