program test
implicit none
real(dp),allocatable :: a(:), b(:)
allocate (a(10))
a = 1.d0
(*) b = a
end program
在上面的代码中,我设置了两个可分配变量-a
和b
-,并且仅a
在代码中分配了。我希望代码无法编译,但是编译良好,并且似乎在下面的代码(显示类似功能)显示SEGFAULT的情况下工作良好。
program test_fail
implicit none
real(dp),allocatable :: a(:), b(:)
integer :: i
allocate ( a(10) )
a = 1.d0
do i = 1, 10
b(i) = a(i)
enddo
end program
可以理解以前的代码会b
自动分配吗?
subroutine test_sub(a)
implicit none
real(dp),intent(inout) :: a(:,:)
...
end program
而且在上述带有整形数组输入的子例程中,是否可以理解代码会自动检测输入数组的大小a
,并在子例程中分配其自己的数组并将其分配回上一级框架,这还不错吗?
最后,将数组复制到另一个数组时哪个更快?
program speed1
implicit none
real(dp), allocatable :: a(:,:,:), b(:,:,:)
allocate( a(10000,10000,10000) )
a = 1.d0
b = a
end program
program speed2
implicit none
real(dp), allocatable :: a(:,:,:), b(:,:,:)
integer :: i, j, k
allocate( a(10000,10000,10000), b(10000,10000,10000) )
a = 1.d0
do i = 1,10000
do j = 1,10000
do k = 1,10000
b(i,j,k) = a(i,j,k)
enddo
enddo
enddo
end program
让我扩展我的评论作为答案。
第一代码剪断编译因为b
需要的形状a
,在分配b=a
,这是Fortran标准特征
第二片段是错误的:未分配的阵列不能被索引,它没有形状或条目。因此存在段错误。
(在这种简单情况下,编译器可以很容易地在编译时检测到该错误并给出错误。但是可分配数组可以在子例程之间传递,并在那里进行分配/取消分配,这使得在一般情况下很难检测到该错误。这就是为什么,我想此检查尚未完成。)
第三代码段:一个assumed-shape
阵列a(:,:)
在子程序/函数的参数,采用的形状和阵列的值被传递给该例程。(通常)它将是对同一内存的引用。
第4个和第5个代码段:Fortran数组的column-major
意思是最左边的索引应该是最里面的循环等,以加快执行速度。喜欢:
do k = 1, n
do j = 1, n
do i = 1, n
b(i,j,k) = a(i,j,k)
但是,在简单情况下,编译器将在应用优化时(例如使用gfortran -O3
)解决此问题。
由于b
未使用,可能是编译器在两种情况下都删除了复制操作。
复制很少会遇到瓶颈,因此b=a
无论性能如何,我都会使用它,因为它很清楚而且很简短。无论如何,上面的循环a=b
可能与编译器等效。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句