初始化大型静态数组时,为什么Fortran 90编译会花费很长时间? [英] Why does Fortran 90 compilation takes very long when large static array are initialized?

查看:186
本文介绍了初始化大型静态数组时,为什么Fortran 90编译会花费很长时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 双精度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分钟)。



第一季度:原因是什么,我该如何避免?



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



第二季度:是否可以在没有主程序的情况下将初始化放在子例程之外,从而避免每次调用子例程时都进行初始化? / p>

编辑



它是常数。在声明语句中初始化它会像这样吗?

 双精度A(56136:8)= reshape(/ * 
&#,#,#,#,#,#,#,#,
&#,#,#,#,#,#,#,#,#,

& * /,(56136,8))

这不起作用,因为有太多

解决方案

我用10000个整数进行了测试,使用 DATA 语句。我的数组包含50000个整数,但想查看是否可以以10000为单位分配它们。

 程序Console1 
隐式无
!变量
整数A(50000)

数据A(1:10000)/& ! 1000行,每个行跟随10个数字:
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 /

!将前10000个元素追加到其余数组
A(10001:50000)= [A(1:10000),A(1:10000),A(1:10000),A(1:10000)]

打印*,A(9998:10002)

最终程序Console1






编辑1



这是使用<$ c的方法$ c> DATA 语句和 COMMON 块可在子例程中设置值。请注意,几乎不赞成使用通用块。

 子例程A_Fill ()
隐式无
整数:: A(10)
common / vals / A
data A / 1,2,3,4,5,6,7,8 ,9,10 /

结束子程序

程序Console1
隐式无
!变量
整数:: A(10)
common / vals / A

call A_Fill()
print *,A

end程序Console1






编辑2



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

 函数A_Fill()result(B)
隐式无
整数:: B(10)
整数,保存:: A(10)
数据A / 1,2,3,4,5,6,7,8,9,10 /
B = A
终端功能

程序Console1
隐式无
接口
函数A_Fill()result(B)
隐式无
整数:: B(10)
终端函数
终端接口
!变量
整数:: A(10)

A = A_Fill()
print *,A

最终程序Console1


I need to initialize an static array in a Fortran subroutine

double precision A(56136,8)

like so:

  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

The latter is generated by another program.

Compilation with ifort 13.0 ifort file.f -O0 takes very long (around 30 minutes).

Q1: What is the reason for this and how can I avoid it?

I have no handle on the main program, the subroutine is linked to third party files. The subroutine is called very often, so file access is not desirable.

Q2: Can I put the initialization outside the subroutine, without having a main program, avoiding the initialization every time the subroutine is called?

Edit

It is constant. Initializing it in the declaration statement would look like this?

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

This does not work because there are too many newlines.

解决方案

I did a test with 10000 integers and it compiles in seconds when using a DATA statement. My array holds 50000 integers but wanted to see if I can assign them in blocks of 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


Edit 1

Here is how do use a DATA statement with a COMMON block to set the values inside a subroutine. Note that use of common blocks is nearly deprecated.

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


Edit 2

Another solution that uses a function to copy the saved array into a secondary working copy.

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

这篇关于初始化大型静态数组时,为什么Fortran 90编译会花费很长时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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