簡體   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