【发布时间】:2018-06-06 14:20:48
【问题描述】:
我有兴趣加快子程序 Compoundret 的计算时间,它基本上是在某个持有期(比如一个月、三个月、六个月等)内复合每月回报序列。 我将从 R 调用这个子例程作为 dll。我在附加的代码 sn-p 中编写了一个 main 函数,以使一切都在 fortran 中运行。
subroutine compoundret(R_c, R, RF, horizons, Tn, N, M)
implicit none
! Arguments declarations
integer, intent(in) :: horizons(M), Tn, N, M
real*8, intent(in) :: RF(Tn), R(Tn, N, M)
real*8, intent(out) :: R_c(Tn, N, M)
! Intermediary Variables
integer :: t, j, k
real*8 :: RF_Temp(Tn, N, M)
R_c = 0.0
do t = 1, Tn
RF_Temp(t,:,:) = RF(t)
end do
!$acc data copyin(r(Tn,N,M), RF_Temp(Tn,N,M), horizons(M)), create(R_c(Tn,
N, M))
!$acc parallel loop
do k = 1, M
do j = 1, N
do t = 1, Tn - horizons(k) + 1
R_c( t, j, k) = PRODUCT( 1 + R( t:t + horizons(k) - 1, j, k) + &
RF_Temp( t:t + horizons(k) - 1, j, k)) - &
PRODUCT(1+ RF_Temp( t:t + horizons(k) - 1, j, k))
end do
end do
end do
!$acc end parallel
!$acc update host(R_c)
!$acc end data
end subroutine compoundret
Program main
implicit none
real*8 :: df(1000,5000, 6)
real*8 :: retdata(size(df,1),size(df,2),size(df,3)),RF(size(df,1))
integer :: horizons(6), Tn, N, M
Tn = size(df, 1)
N = size(df, 2)
M = size(df, 3)
df = 0.001
RF = 0.001
horizons(:) = (/1,3,6,12,24,48/)
call compoundret(retdata,df,RF,horizons, Tn, N, M)
print*, retdata(1, 1, 1:M)
结束程序 我的目标平台是计算 6.0 设备 (GTX 1060)。
【问题讨论】:
-
这不是 CUDA 而是 OpenACC
-
@Chiel 这是一个 OpenACC 代码,但我不介意通过 Cuda Fortran 内核将循环内的所有内容完全卸载到 GPU。
-
检查临时数组的分配需要多长时间以及内存传输到GPU需要多长时间。
-
@VladimirF 这在 Fortran 中是否允许?在 C/C++ 中,这种表示法意味着堆栈分配,并且很可能导致堆栈溢出,因为如果数组不大,OP 可能不想优化此代码。
-
编译器可以按照它想要的任何方式进行分配。不暗示堆栈分配。在这个程序中它是 228 MB。
标签: fortran openacc acceleration