如何减少数据移动以提高性能

时间:2019-05-14 17:18:42

标签: fortran gfortran openacc

我正在尝试使用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

我希望减少计算时间,代码可以在没有数据区域的情况下运行,但是速度很慢,并且在使用数据区域时,由于无法分解,程序会停止

1 个答案:

答案 0 :(得分:1)

OpenACC计算区域(即“内核”或“并行”)包括隐式数据区域。如果不在与结构化数据区域相同的范围内,并且在计算区域上没有任何数据子句,则编译器将为您隐式复制数据。添加数据区域将覆盖此隐式数据,使您可以更好地控制何时传输数据。

您在数据区域看到的错误最有可能是由于在“ copy”和“ create”子句中都放置了“ a”。由于变量只能出现一次,因此将使用最右边的子句(即create),因此不会将数据复制到设备或从设备复制数据。要修复,请删除create子句。 (请注意,副本将创建并复制)

但是,由于您的数据区域直接位于计算区域的周围,因此您的性能将保持不变。为了解决这个问题,我建议将数据区域移到代码中更早的位置,例如在分配或初始化“ a”之后。然后在“内核”指令中添加“ present(a)”子句以强制数据存在于设备上。

要确保主机和设备之间的数据同步,请在计算区域之前和之后使用“ update”指令。下一步是开始向外移动“更新”指令,同时将更多计算卸载到设备上。理想情况下,您应该卸载可在“ A”阵列上运行的所有代码,以便在程序启动时将数据复制到设备一次,并在需要打印结果时将数据复制回到主机。