如何减少数据移动以提高性能
how to reduce data movement to improve performance
我正在尝试使用 openACC 提高 Fortran 代码的性能,但是编译器显示设备和主机之间有很多传输
我尝试使用数据区域来减少内存移动
这是代码的一部分,
完整的子程序用于使用 LU
求解方程
!EXCHANGING AND ELIMINATING COLUMNS
!$acc data copy(a(:,k:n))create(a(:,k:n))
!$acc kernels
DO J = K + 1, N
TQ = A(M, J)
A(M, J) = A(K, J)
A(K, J) = TQ
IF (DABS(TQ) .GT. 0) THEN
DO I = K + 1,N
A(I,J)=A(I,J)+A(I,K)*TQ
ENDDO
END IF
ENDDO
!$acc end kernels
!$acc end data
我希望减少计算时间,代码在没有数据区域的情况下运行但非常慢,并且在使用数据区域时,程序因不可能的因式分解而停止
OpenACC 计算区域,即 "kernels" 或 "parallel",包括隐式数据区域。当与结构化数据区域不在同一范围内并且计算区域上没有任何数据子句时,编译器将为您隐式复制数据。添加数据区域将覆盖此隐式数据,并让您更好地控制何时传输数据。
您在数据区域看到的错误很可能是由于在 "copy" 和 "create" 子句中都放置了 "a"。由于变量只能出现一次,因此将使用最右边的子句(即创建),因此您的数据不会被复制到设备或从设备复制。要修复,请删除 create 子句。 (注意 copy 会做一次创建和复制)
但是,由于您的数据区域直接围绕着计算区域,因此您的性能将保持不变。为了解决这个问题,我建议将数据区域移动到代码中更早的位置,例如直接在分配或初始化 "a" 之后。然后将 "present(a)" 子句添加到 "kernels" 指令以强制数据存在于设备上。
为确保主机和设备之间的数据同步,请在计算区域前后使用 "update" 指令。下一步是开始向外移动 "update" 指令,同时向设备卸载更多计算。理想情况下,您将卸载所有在 "A" 数组上运行的代码,以便在程序开始时将数据复制到设备一次,并在需要打印结果时复制回主机。
我正在尝试使用 openACC 提高 Fortran 代码的性能,但是编译器显示设备和主机之间有很多传输
我尝试使用数据区域来减少内存移动
这是代码的一部分, 完整的子程序用于使用 LU
求解方程!EXCHANGING AND ELIMINATING COLUMNS
!$acc data copy(a(:,k:n))create(a(:,k:n))
!$acc kernels
DO J = K + 1, N
TQ = A(M, J)
A(M, J) = A(K, J)
A(K, J) = TQ
IF (DABS(TQ) .GT. 0) THEN
DO I = K + 1,N
A(I,J)=A(I,J)+A(I,K)*TQ
ENDDO
END IF
ENDDO
!$acc end kernels
!$acc end data
我希望减少计算时间,代码在没有数据区域的情况下运行但非常慢,并且在使用数据区域时,程序因不可能的因式分解而停止
OpenACC 计算区域,即 "kernels" 或 "parallel",包括隐式数据区域。当与结构化数据区域不在同一范围内并且计算区域上没有任何数据子句时,编译器将为您隐式复制数据。添加数据区域将覆盖此隐式数据,并让您更好地控制何时传输数据。
您在数据区域看到的错误很可能是由于在 "copy" 和 "create" 子句中都放置了 "a"。由于变量只能出现一次,因此将使用最右边的子句(即创建),因此您的数据不会被复制到设备或从设备复制。要修复,请删除 create 子句。 (注意 copy 会做一次创建和复制)
但是,由于您的数据区域直接围绕着计算区域,因此您的性能将保持不变。为了解决这个问题,我建议将数据区域移动到代码中更早的位置,例如直接在分配或初始化 "a" 之后。然后将 "present(a)" 子句添加到 "kernels" 指令以强制数据存在于设备上。
为确保主机和设备之间的数据同步,请在计算区域前后使用 "update" 指令。下一步是开始向外移动 "update" 指令,同时向设备卸载更多计算。理想情况下,您将卸载所有在 "A" 数组上运行的代码,以便在程序开始时将数据复制到设备一次,并在需要打印结果时复制回主机。