复制数组:循环和数组操作

时间:2021-01-04 21:17:03

I work with Fortran now quite a long time but I have a question to which I can't find a satisfying answer. If I have two arrays and I want to copy one into the other:

我和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

But I also noticed that it works as well if I do it like that:

但我也注意到,如果我这样做,它也会起作用:

real,dimension(0:100,0:100) :: array1,array2
...
array1 = array2

And there is a huge difference in computational time! (The second one is much faster!) If I do it without a loop can there be a problem because I don't know maybe I'm not coping the content just the memory reference? Does it change anything if I do another mathematical step like:

计算时间有很大的不同!(第二个要快得多!)如果我没有循环,会不会有问题因为我不知道也许我没有处理内容只是内存引用?如果我再做一个数学步骤,它会改变什么吗?

array1 = array2*5

Is there a problem on a different architecture (cluster server) or on a different compiler (gfortran, ifort)?

在不同的架构(集群服务器)或不同的编译器(gfortran, ifort)上有问题吗?

I have to perform various computational steps on huge amounts of data so the computational time is an issue.

我必须对大量的数据执行各种计算步骤,所以计算时间是个问题。

2 个解决方案

#1


3  

Everything that @Alexander_Vogt said, but also:

@Alexander_Vogt说的每句话,还有:

do i=0,100
    do j=0,100
        array1(i,j) = array2(i,j)
    enddo
enddo

will always be slower than

总是比

do j=0,100
    do i=0,100
        array1(i,j) = array2(i,j)
    enddo
enddo

(Unless the compiler notices it and reorders the loops.)

(除非编译器注意到它并重新排序循环。)

In Fortran, the first parameter is the fastest changing. That means that in the second loop, the compiler can load several elements of the array in one big swoop in the lower level caches to do operations on.

在Fortran语言中,第一个参数变化最快。这意味着在第二个循环中,编译器可以在较低的缓存中以一个大的动作加载数组的几个元素来执行操作。

If you have multidimensional loops, always have the innermost loop loop over the first index, and so on. (If possible in any way.)

如果您有多维循环,则总是在第一个索引上有最内层的循环,依此类推。(如果可能的话。)

#2


1  

Fortran is very capable of performing vector operations. Both

Fortran非常有能力执行向量运算。这两个

array1 = array2

and

array1 = array2*5

are valid operations. This notation allows the compiler to efficiently parallelize (and/or) optimize the code, as no dependence on the order of the operations exists.

是有效的操作。这种符号允许编译器有效地并行化(和/或)优化代码,因为不依赖于操作的顺序。

However, these construct are equivalent to the explicit loops, and it depends on the compiler which one will be faster.

但是,这些构造等价于显式循环,它取决于编译器哪个更快。

Whether the memory will be copied or not depends on what further is done with the arrays and whether the compiler can optimize that. If there is no performance gain, it is safe to assume the array will be copied.

内存是否会被复制取决于对数组做了什么,以及编译器是否能够优化它。如果没有性能提升,那么可以安全地假设数组将被复制。

#1


3  

Everything that @Alexander_Vogt said, but also:

@Alexander_Vogt说的每句话,还有:

do i=0,100
    do j=0,100
        array1(i,j) = array2(i,j)
    enddo
enddo

will always be slower than

总是比

do j=0,100
    do i=0,100
        array1(i,j) = array2(i,j)
    enddo
enddo

(Unless the compiler notices it and reorders the loops.)

(除非编译器注意到它并重新排序循环。)

In Fortran, the first parameter is the fastest changing. That means that in the second loop, the compiler can load several elements of the array in one big swoop in the lower level caches to do operations on.

在Fortran语言中,第一个参数变化最快。这意味着在第二个循环中,编译器可以在较低的缓存中以一个大的动作加载数组的几个元素来执行操作。

If you have multidimensional loops, always have the innermost loop loop over the first index, and so on. (If possible in any way.)

如果您有多维循环,则总是在第一个索引上有最内层的循环,依此类推。(如果可能的话。)

#2


1  

Fortran is very capable of performing vector operations. Both

Fortran非常有能力执行向量运算。这两个

array1 = array2

and

array1 = array2*5

are valid operations. This notation allows the compiler to efficiently parallelize (and/or) optimize the code, as no dependence on the order of the operations exists.

是有效的操作。这种符号允许编译器有效地并行化(和/或)优化代码,因为不依赖于操作的顺序。

However, these construct are equivalent to the explicit loops, and it depends on the compiler which one will be faster.

但是,这些构造等价于显式循环,它取决于编译器哪个更快。

Whether the memory will be copied or not depends on what further is done with the arrays and whether the compiler can optimize that. If there is no performance gain, it is safe to assume the array will be copied.

内存是否会被复制取决于对数组做了什么,以及编译器是否能够优化它。如果没有性能提升,那么可以安全地假设数组将被复制。