cuda fortran加速

时间:2012-07-23 13:04:15

标签: cuda fortran

我正在尝试评估一个简单的cuda fortran代码的加速:数组的增量。

CPU版本:

module simpleOps_m
contains
subroutine increment (a, b)
implicit none
integer , intent ( inout ) :: a(:)
integer , intent (in) :: b
integer :: i, n

n = size (a)
do i = 1, n
a(i) = a(i)+b
enddo

end subroutine increment
end module simpleOps_m


program incrementTest
use simpleOps_m
implicit none
integer , parameter :: n = 1024*1024*100
integer :: a(n), b

a = 1
b = 3


call increment (a, b)


if ( any(a /= 4)) then
write (* ,*) '**** Program Failed **** '
else
write (* ,*) 'Program Passed '
endif
end program incrementTest

GPU版本:

module simpleOps_m
contains
attributes ( global ) subroutine increment (a, b)
implicit none
integer , intent ( inout ) :: a(:)
integer , value :: b
integer :: i, n

n = size (a)

do i=blockDim %x*( blockIdx %x -1) + threadIdx %x ,n, BlockDim %x* GridDim %x
    a(i) = a(i)+b
end do

end subroutine increment
end module simpleOps_m

program incrementTest
use cudafor
use simpleOps_m
implicit none
integer , parameter :: n = 1024*1024*100
integer :: a(n), b
integer , device :: a_d(n)
integer :: tPB = 256

a = 1
b = 3

a_d = a
call increment <<< 128,tPB >>>(a_d , b)
a = a_d

if ( any(a /= 4)) then
write (* ,*) '**** Program Failed **** '
else
write (* ,*) 'Program Passed '
endif
end program incrementTest

所以我用pgf90编译了两个版本 http://www.pgroup.com/resources/cudafortran.htm

使用“time”命令评估执行时间,我得到:


表示CPU版本

$ time(cpu executable)

真实0m0.715s

用户0m0.410s

sys 0m0.300s


for GPU version

$ time(gpu可执行文件)

真实的0m1.057s

用户0m0.710s

sys 0m0.340s


因此加速=(CPU exec.time)/(GPU exec.time)是&lt; 1 有什么理由说明为什么加速不是> 1应该达到什么?

提前致谢

1 个答案:

答案 0 :(得分:1)

这里的问题是,在这个相当人为的例子中,初始化主机上的大型数组(a=1)的成本几乎与增加数组内容的循环成本相同​​,这是部分在GPU上并行化的代码。由于并行工作的总量与串行工作的总量大致相同,因此Amdahl's Law通过并行化GPU上的某些代码来实现任何显着的加速,从而大量堆叠。

通过将初始化和增量操作融合到GPU上的单个并行操作中,可以实现更显着的加速。

[这个答案已经从评论中汇总而成,并作为社区维基条目添加,以便将这个问题从CUDA标签的未答复列表中删除]

相关问题