假设我在Fortran A(:,:,:,:)中有一个多维数组,其中每个维数的大小都是相同的,即n。
我想换一下第二和第三个维度。我可以重塑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,我得到了(我运行了三次)
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似乎不是很有效。
(在How to speed up reshape in higher rank tensor contraction by BLAS in Fortran?中,报告定时的代码样式跟随在答案之后)
发布于 2021-04-01 20:29:10
为什么不试着将reshape与显式循环进行比较,比如
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。
https://stackoverflow.com/questions/66901672
复制相似问题