我想将元素添加到一维矩阵 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/