我最近一直在处理一些代码,要求我将数组中的元素向左,向右,向上和向下移位(取决于索引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列会被复制到......第3列不会像第1列那样转移数据列覆盖了左边的所有内容。
如果我翻转指数,
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
事情很好,向左或向右移动。我怀疑编译器在第二种情况下检测到连续内存的就地更新,因此它会在引擎盖下进行临时复制。避免重写问题,但这只是我的猜测。任何人都可以更详细地解释为什么班次以一种方式而不是另一种方式起作用?