0

私は最近、配列内の要素を左、右、上、下にシフトする必要があるコードに取り組んでいます ( index に応じて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にコピーされ、列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

物事はうまく機能し、左または右にシフトします。コンパイラは2番目のケースで連続メモリのインプレース更新を検出すると思われるため、上書きの問題を回避するために「ボンネットの下」で一時的なコピーを作成しますが、それは私の推測です。シフトが一方の方向に機能し、他方の方向には機能しない理由について、誰かがより詳細な説明をすることができますか?

4

0 に答える 0