我正在嘗試在 fortran 中優化以下型別的陣列乘法:
do i = 1, n
do j = 1, n
do k = 1, n
do i1 = 1, n
do j1 = 1, n
do k1 = 1, n
B(k1,j1,i1) = B(k1,j1,i1) &
A(k,j,i)*v1(k,k1)*v2(j,j1)*v3(i,i1)
enddo
enddo
enddo
enddo
enddo
enddo
這里 A 和 B 的大小為 (n,n,n),而 v1、v2 和 v3 的大小為 (n,n)。似乎應該有某種矢量化可以讓我加快這個評估。我嘗試了不同的索引排序。有沒有更快的計算 B 的方法?
編輯:
好的,可以使用 matmul 獲得大約 10 倍的加速:
do i = 1, n
do i1 = 1, n
do j = 1, n
do j1 = 1, n
B(:,j1,i1) = B(:,j1,i1) &
matmul(A(:,j,i),v1)*v2(j,j1)*v3(i,i1)
enddo
enddo
enddo
enddo
我們還能做得更好嗎?
uj5u.com熱心網友回復:
您至少可以使用matmulBLAS/LAPACK 或 BLAS/LAPACK 將兩個回圈對減少為矩陣乘法,例如
do i1=1,n
do i=1,n
B(:,:,i1) = B(:,:,i1) &
& matmul(matmul(transpose(v1), A(:,:,i)), v2) * v3(i,i1)
enddo
enddo
您幾乎可以肯定通過快取 double 的結果來進一步加快速度matmul,例如
real :: intermediate(n,n,n)
do i=1,n
intermediate(:,:,i) = matmul(matmul(transpose(v1), A(:,:,i)), v2)
enddo
do i1=1,n
do i=1,n
B(:,:,i1) = B(:,:,i1) intermediate(:,:,i) * v3(i,i1)
enddo
enddo
反過來可能會加快速度matmul,例如
real :: intermediate(n,n,n)
do i=1,n
intermediate(:,:,i) = matmul(matmul(transpose(v1), A(:,:,i)), v2)
enddo
do j1=1,n
B(:,j1,:) = matmul(intermediate(:,j1,:), v3))
enddo
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/417260.html
標籤:
