[英]Fast swap two dimension in an array in Fortran
假設我在 Fortran A(:,:,:,:)
中有一個多維數組,其中每個維度的大小相同, n
。
我想交換第二維和第三維。 我可以做一個 reshape A2 = reshape(A, (/ n, n, n, n/), order = (/1,3,2,4/) )
有沒有更快的方法? 因為我只需要部分交換。
更新的示例代碼
Program reshape_test
Use, Intrinsic :: iso_fortran_env, Only : wp => real64, li => int64
real :: A(32,32,32,32), A2(32,32,32,32)
integer :: i,j,k,l,n,m, m_iter
Integer( li ) :: start, finish, rate
m_iter = 3200
n = 32
do l = 1, n
do k = 1, n
do j = 1, n
do i = 1, n
A(i,j,k,l) = i + j * k**2 - l
end do
end do
end do
end do
Call System_clock( start, rate )
do m=1,m_iter
A2 = reshape(A, (/n, n, n, n/), order = (/1,3,2,4/) )
end do
! write (*,*) A(1,2,3,4), A(1,3,2,4), A2(1,2,3,4), A2(1,3,2,4)
Call System_clock( finish, rate )
Write(*,*) 'Time for reshape-1', Real( finish - start, wp ) / rate
Call System_clock( start, rate )
do m=1,m_iter
do j = 1, n
do i = 1, n
A2(:,i,j,:) = A(:,j,i,:)
end do
end do
end do
!write (*,*) A(1,2,3,4), A(1,3,2,4), A2(1,2,3,4), A2(1,3,2,4)
Call System_clock( finish, rate )
Write(*,*) 'Time for reshape-2', Real( finish - start, wp ) / rate
Call System_clock( start, rate )
do m=1,m_iter
do l = 1, n
do k = 1, n
do j = 1, n
do i = 1, n
A2(i,k,j,l) = A(i,j,k,l)
end do
end do
end do
end do
end do
! write (*,*) A(1,2,3,4), A(1,3,2,4), A2(1,2,3,4), A2(1,3,2,4)
Call System_clock( finish, rate )
Write(*,*) 'Time for reshape-3', Real( finish - start, wp ) / rate
end program reshape_test
在這個例子中,通過gfortran -o3
,我得到了(我運行了 3 次)
Time for reshape-1 13.500307800000000
Time for reshape-2 10.146418400000000
Time for reshape-3 20.489294800000000
Time for reshape-1 11.421597100000000
Time for reshape-2 9.3823936999999997
Time for reshape-3 19.856221900000001
Time for reshape-1 14.376207500000000
Time for reshape-2 10.756465400000000
Time for reshape-3 21.301044500000000
添加-march=native
導致(我運行了三遍)
Time for reshape-1 12.517529200000000
Time for reshape-2 10.240939200000000
Time for reshape-3 26.637998799999998
Time for reshape-1 12.436479700000000
Time for reshape-2 9.9803838000000002
Time for reshape-3 21.760061700000001
Time for reshape-1 11.419214300000000
Time for reshape-2 10.908747200000001
Time for reshape-3 21.445951399999998
總體方法 2 是最快的。 -march=native
似乎不是很有效。
(報告時間的代碼樣式遵循如何通過 Fortran 中的 BLAS 在高階張量收縮中加速重塑? )
您為什么不嘗試將重塑與顯式循環進行比較
do i = 1, n
do j = 1, n
do k = 1, n
do l = 1, n
A2(i,k,j,l) = A(i,j,k,l)
end do
end do
end do
end do
然后你告訴我們答案。 它也可能取決於優化。 我建議-O3 -march=native
,並嘗試更改為-O2
、 -O1
和-O0
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.