繁体   English   中英

在 Fortran 中的数组中快速交换二维

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM