为什么Fortran 90编译在初始化大型静态数组时需要很长时间?

时间:2017-08-16 09:11:17

标签: arrays compilation fortran initialization

我需要在Fortran子例程中初始化静态数组

double precision A(56136,8)
像这样:

  A(1,1)=0.999950528145
  A(1,2)=0.99982470274
  A(1,3)=0.999987006187
  .
  .
  .
  A(56136,7)=0.933468163013
  A(56136,8)=0.0668926686049

后者由另一个程序生成。

使用ifort 13.0编译ifort file.f -O0需要很长时间(大约30分钟)。

Q1:这是什么原因,我该如何避免呢?

我没有处理主程序,子程序链接到第三方文件。子例程经常被调用,因此不希望文件访问。

Q2:我可以在没有主程序的情况下将初始化放在子程序之外,每次调用子程序时都避免初始化吗?

修改

这是不变的。在声明语句中初始化它看起来像这样吗?

  double precision A(56136:8)=reshape(/*
 &             #, #, #, #, #, #, #, #,
 &             #, #, #, #, #, #, #, #,
 :
 &            */,(56136,8))

这不起作用,因为新行太多了。

1 个答案:

答案 0 :(得分:0)

我使用10000个整数进行了测试,并在使用DATA语句时在几秒钟内编译。我的数组拥有50000个整数但想看看我是否可以用10000块来分配它们。

program Console1
implicit none
! Variables
integer A(50000)

data A(1:10000) / &       ! 1000 lines of 10 numbers each to follow:
      2,     3,     5,     7,    11,    13,    17,    19,    23,    29, &
     31,    37,    41,    43,    47,    53,    59,    61,    67,    71, &
     73,    79,    83,    89,    97,   101,   103,   107,   109,   113, &
    127,   131,   137,   139,   149,   151,   157,   163,   167,   173, &
    179,   181,   191,   193,   197,   199,   211,   223,   227,   229, &
    233,   239,   241,   251,   257,   263,   269,   271,   277,   281, &
...
 104087,104089,104107,104113,104119,104123,104147,104149,104161,104173, &
 104179,104183,104207,104231,104233,104239,104243,104281,104287,104297, &
 104309,104311,104323,104327,104347,104369,104381,104383,104393,104399, &
 104417,104459,104471,104473,104479,104491,104513,104527,104537,104543, &
 104549,104551,104561,104579,104593,104597,104623,104639,104651,104659, &
 104677,104681,104683,104693,104701,104707,104711,104717,104723,104729 /

! Append the first 10000 elements to the remaining array
A(10001:50000) = [A(1:10000),A(1:10000),A(1:10000),A(1:10000)]

print *, A(9998:10002)

end program Console1

修改1

以下是如何使用DATA语句和COMMON块来设置子例程中的值。请注意,使用公共块几乎已弃用。

subroutine A_Fill()
implicit none
integer :: A(10)
common /vals/ A
data A/ 1,2,3,4,5,6,7,8,9,10 /

end subroutine

program Console1
implicit none
! Variables
integer :: A(10)
common /vals/ A

call A_Fill()
print *, A

end program Console1

修改2

使用函数将已保存的数组复制到辅助工作副本的另一种解决方案。

function A_Fill() result(B)
implicit none
integer :: B(10)
integer,save :: A(10)
data A/ 1,2,3,4,5,6,7,8,9,10 /
    B = A
end function

program Console1
implicit none   
interface 
    function A_Fill() result(B)
    implicit none
    integer :: B(10)
    end function        
end interface
! Variables
integer :: A(10)

A = A_Fill()    
print *, A

end program Console1