[英]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.