我现在与Fortran合作很长一段时间,但我有一个问题,我无法找到令人满意的答案。 如果我有两个数组,我想将一个数组复制到另一个数组中:
real,dimension(0:100,0:100) :: array1,array2
...
do i=0,100
do j=0,100
array1(i,j) = array2(i,j)
enddo
enddo
但是我也注意到,如果我这样做,它也会起作用:
real,dimension(0:100,0:100) :: array1,array2
...
array1 = array2
计算时间差异很大! (第二个更快!) 如果我在没有循环的情况下这样做就会出现问题,因为我不知道也许我不会仅仅根据内存参考来处理内容? 如果我做另一个数学步骤,它会改变什么:
array1 = array2*5
在不同的架构(集群服务器)或不同的编译器(gfortran,ifort)上是否存在问题?
我必须对大量数据执行各种计算步骤,因此计算时间是一个问题。
答案 0 :(得分:3)
@Alexander_Vogt所说的一切,还有:
do i=0,100
do j=0,100
array1(i,j) = array2(i,j)
enddo
enddo
总是慢于
do j=0,100
do i=0,100
array1(i,j) = array2(i,j)
enddo
enddo
(除非编译器注意到它并重新排序循环。)
在Fortran中,第一个参数是变化最快的。这意味着在第二个循环中,编译器可以在较低级别的缓存中一次性加载数组的多个元素以进行操作。
如果你有多维循环,总是在第一个索引上面有最里面的循环循环,依此类推。 (如果可能的话。)
答案 1 :(得分:1)
Fortran非常有能力执行向量运算。两者
array1 = array2
和
array1 = array2*5
是有效的操作。 这种表示法允许编译器有效地并行化(和/或)优化代码,因为不存在对操作顺序的依赖。
但是,这些构造等同于显式循环,它取决于编译器哪个更快。
是否复制内存取决于数组的进一步操作以及编译器是否可以对其进行优化。如果没有性能增益,则可以安全地假设将复制阵列。