Fortran 如何仅使用一个索引在数组上循环?

Fortran 如何仅使用一个索引在数组上循环?,fortran,Fortran,我在F90中有这样的代码: real(8), dimension(10,10,10) :: A do i = 1, 1000 print*,A(i,1,1) enddo 我很惊讶这能起作用,它比简单地通过I,j,k在3维上循环要快 有人能解释一下为什么这样做吗?你的代码是非法的。但是在引擎盖下,数组的内存布局恰好是按列的大顺序排列的,就像在三重循环k,j,i中一样,因此代码似乎可以工作。但这是非法的 如果在编译器中启用运行时错误检查(请参阅手册),它将查找错误并报告它 如果不启用编译器优

我在F90中有这样的代码:

real(8), dimension(10,10,10) :: A

do i = 1, 1000

print*,A(i,1,1)

enddo
我很惊讶这能起作用,它比简单地通过
I,j,k
在3维上循环要快


有人能解释一下为什么这样做吗?

你的代码是非法的。但是在引擎盖下,数组的内存布局恰好是按列的大顺序排列的,就像在三重循环k,j,i中一样,因此代码似乎可以工作。但这是非法的

如果在编译器中启用运行时错误检查(请参阅手册),它将查找错误并报告它

如果不启用编译器优化,它可能会稍微快一点,因为嵌套循环中会有一些开销,但是优化编译器会将代码优化为一个循环

如果您真的这样做了(您应该始终显示您的代码!!!

然后请注意,这是错误的顺序,你应该在k,j,i顺序中循环


另外,请注意,测量屏幕上的打印速度是没有用的,可能会非常棘手。有些数学运算更有用。

您的代码是非法的。但是在引擎盖下,数组的内存布局恰好是按列的大顺序排列的,就像在三重循环k,j,i中一样,因此代码似乎可以工作。但这是非法的

如果在编译器中启用运行时错误检查(请参阅手册),它将查找错误并报告它

如果不启用编译器优化,它可能会稍微快一点,因为嵌套循环中会有一些开销,但是优化编译器会将代码优化为一个循环

如果您真的这样做了(您应该始终显示您的代码!!!

然后请注意,这是错误的顺序,你应该在k,j,i顺序中循环


另外,请注意,测量屏幕上的打印速度是没有用的,可能会非常棘手。有些数学运算更有用。

比什么运算快?在代码中,您到底不了解什么?数组A的维度是10X10X10,那么,当索引I超过10时,为什么我上面提供的代码可以工作?它比下面的速度快,i=1,10doj=1,10dok=1,10print*,比什么快?在代码中,您到底不了解什么?数组A的维度是10X10X10,那么,当索引I超过10时,为什么我上面提供的代码可以工作?它比下面的速度快,i=1,10DoJ=1,10DoK=1,10Print*,A(i,j,k)enddo enddo enddo谢谢你的回答!虽然我遵守了标志mpif90-O3-heaparrays-cpp,但A(I,1,1)的速度几乎是A(I,j,k)的10倍。我用A做的是一些计算,但是打印。上面的代码是我从开源代码中学到的。打印1000行并不是真正瓶颈的一个很好的例子。尝试在如此小和复杂的东西上运行计时可能会产生误导。在3D情况下,您执行循环的顺序是什么?正如弗拉基米尔所说,这一点非常重要,在许多情况下,这会导致性能上的一个数量级差异!虽然我遵守了标志mpif90-O3-heaparrays-cpp,但A(I,1,1)的速度几乎是A(I,j,k)的10倍。我用A做的是一些计算,但是打印。上面的代码是我从开源代码中学到的。打印1000行并不是真正瓶颈的一个很好的例子。尝试在如此小和复杂的东西上运行计时可能会产生误导。在3D情况下,您执行循环的顺序是什么?正如弗拉基米尔所说,这一点非常重要,在许多情况下会导致性能上的数量级差异
do i=1,10
  do j=1,10
    do k=1,10
      something with A(i,j,k)