[英]Fast swap two dimension in an array in Fortran
Suppose I have a multi-dimension array in Fortran A(:,:,:,:)
, where the size of each dimension is the same, n
.假设我在 Fortran
A(:,:,:,:)
中有一个多维数组,其中每个维度的大小相同, n
。
I would like to swap the second and third dimension.我想交换第二维和第三维。 I can do a reshape
A2 = reshape(A, (/ n, n, n, n/), order = (/1,3,2,4/) )
Is there any faster way?我可以做一个 reshape
A2 = reshape(A, (/ n, n, n, n/), order = (/1,3,2,4/) )
有没有更快的方法? Since I only need a partial swap.因为我只需要部分交换。
Updated Example code更新的示例代码
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
In this example, by gfortran -o3
, I got (I run three times)在这个例子中,通过
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
Adding -march=native
leads to (I run three times)添加
-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
Overall approach 2 is the fastest.总体方法 2 是最快的。
-march=native
seems not very effective. -march=native
似乎不是很有效。
(code style of report timing follows answer in How to speed up reshape in higher rank tensor contraction by BLAS in Fortran? ) (报告时间的代码样式遵循如何通过 Fortran 中的 BLAS 在高阶张量收缩中加速重塑? )
Why don't you try to compare reshape with explicit loops like您为什么不尝试将重塑与显式循环进行比较
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
and then you tell us the answer.然后你告诉我们答案。 It could also depend on optimization.
它也可能取决于优化。 I would suggest
-O3 -march=native
, and try changing to -O2
, -O1
and -O0
.我建议
-O3 -march=native
,并尝试更改为-O2
、 -O1
和-O0
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.