我最近一直在处理一些代码,这些代码需要我将数组中的元素向左、向右、向上和向下移动(取决于索引i
)。我的第一个想法是尝试这样的事情:
subroutine shift(f)
real, intent(inout) :: f(0:8, rDim, cDim)
real :: periodicHor(rDim)
periodicHor(:) = f(1,:,cDim)
f(1,:,2:cDim) = f(1,:,1:cDim - 1)
f(1,:,1) = periodicHor(:)
!and so on for directions 2:8
end subroutine
但是,当我以这种方式进行布局时,第 1 列被复制到第 2 列,第 2 列被复制到第 3 列,第 3 列被复制到……这并不是数据的转移,而是第一列覆盖了左边的所有内容。
但是,如果我翻转索引,
subroutine betterShift(f)
real, intent(inout) :: f(rDim, cDim, 0:8)
real :: periodicHor(rDim)
periodicHor(:) = f(:,cDim,1)
f(:,2:cDim,1) = f(:,1:cDim - 1,1)
f(:,1,1) = periodicHor(:)
end subroutine
一切正常,向左或向右移动。我怀疑编译器在第二种情况下检测到连续内存的就地更新,因此它会“在后台”制作一个临时副本以避免覆盖问题,但这只是我的猜测。谁能更详细地解释为什么这种转变以一种方式而不是另一种方式起作用?