在 fortran (gfortran) 中使用非常大的数组

问题描述

我正在处理非常大的数组,所以一开始当我尝试编译时,由于堆栈大小而收到警告。

警告是:

    4 | integer,dimension(n,5) :: temp1 
 1 Warning: Array ‘temp1’ at (1) is larger than limit set by ‘-fmax-stack-var-size=’,moved from stack to static storage.
 This makes the procedure unsafe when called recursively,or concurrently from multiple threads.
 Consider using ‘-frecursive’,or increase the ‘-fmax-stack-var-size=’ limit,or c – ...

代码就是这样(可能有小错误,但我不认为这是问题所在,因为当我使用小数组时,它可以正确运行):

program fecha
    implicit none
    integer,parameter :: n = 100000
    integer,5) :: temp1
    real,dimension(n) :: temp2

    integer,dimension(:),allocatable :: dia,mes,ano,hora,minuto
    real,allocatable :: abs1
!-------------------------------------------------------------------------
    integer :: i = 1
    integer :: IoUnit,ierr
    character*50 :: formato = '(i2,1x,i2,i4,f7.4)'

    allocate(dia(n),mes(n),ano(n),hora(n),minuto(n))
    allocate(abs1(n))
    dia = 0; mes = 0; ano = 0; hora = 0; minuto = 0; abs1 = 0.0
!-------------------------------------------------------------------------
    open (newunit = IoUnit,file = 'datos_elegidos.txt')
    read(IoUnit,*)

    do
        read(unit = IoUnit,fmt = formato,iostat = ierr) temp1(i,1),temp1(i,2),3),4),5),temp2(i)
        if (ierr /= 0) exit
        write(*,*) temp1(i,temp2(i)
        i = i + 1 
    end do
    i = i-1    
!-------------------------------------------------------------------------
    deallocate(dia,minuto,abs1)
    allocate(dia(i),mes(i),ano(i),hora(i),minuto(i),abs1(i))

    dia(:i) = temp1(:i,1)
    mes(:i) = temp1(:i,2)
    ano(:i) = temp1(:i,3)
    hora(:i) = temp1(:i,4)
    minuto(:i) = temp1(:i,5)
    abs1(:i) = temp2(:i)

    !print*,dia
    close(IoUnit)

end program

这是txt的一部分:

dia mes ano hora min abs370 

 3  6 2016  0  5  30.4570   
 3  6 2016  0 10  27.5388   
 3  6 2016  0 15  23.1983   
 3  6 2016  0 20  22.3339   
 3  6 2016  0 25  22.0864   
 3  6 2016  0 30  20.9339   
 3  6 2016  0 35  21.8094   
 3  6 2016  0 40  21.3255   
 3  6 2016  0 45  22.1972   
 3  6 2016  0 50  21.2331   
 3  6 2016  0 55  21.6099   
 3  6 2016  1  0  20.4057 

解决方法

TL;DR;:忽略或忽略警告,毫无意义

这个警告是 gfortran 10 的一个新特性。我发现它只是噪音。您的代码中没有任何单个 Fortran 过程。因此,不存在递归运行过程的风险,也无需对堆栈执行任何操作(使用 ulimit 或其他工具)。

基本上它说数组被放置到静态存储中。那是内存的固定部分。但它完全没问题!静态存储主程序数据或模块数据或公共块数据或类似数据没有任何问题。

将数据放在静态存储中使数据有效save。但是主程序数据是由 Fortran 标准自动save

我认为主程序的这个警告是编译器缺陷。因此,我提交了错误报告:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98411(在报告之前,我首先检查了重复项,但没有找到。)