【问题标题】:cuda fortran speed-upcuda fortran 加速
【发布时间】:2016-01-10 21:37:40
【问题描述】:

我正在尝试评估简单 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 版本

$ 时间(cpu 可执行文件)

真正的 0m0.715s

用户 0m0.410s

系统 0m0.300s


GPU 版本

$ 时间(gpu 可执行文件)

真正的0m1.057s

用户 0m0.710s

系统 0m0.340s


所以加速=(CPU exec.time)/(GPU exec.time) 1 有什么原因吗?

提前致谢

【问题讨论】:

  • 我无法对此发表任何评论,我没有阅读您的代码,也没有使用 CUDA Fortran 的经验。但总的来说,我不会根据一项大约需要 1 秒的作业的运行时间来得出任何关于加速的结论。得知将数据移入和移出 GPU 的本地内存所花费的时间比 GPU 上的计算在相对较短的工作中节省的时间要长,这并不让我感到惊讶。
  • 没错,即使没有内存传输,获取 GPU 和分配也需要一些时间。
  • 在对 CUDA 或 OpenCL 代码进行基准测试时,应该首先“预热”内核执行,以便在实际基准测试过程开始之前正确获取和初始化所有上下文,以免干扰时间。尽管如此,仍然存在一定的计算量与内存传输量的比率,如果不满足该比率会导致性能下降。
  • 我会分析您的主机 CPU 版本 - 我怀疑 a=3 可能会占用实际向量加法的总执行时间。在这种情况下,艾哈迈达定律很快就会开始对你不利....
  • +1 到@talonmies 评论——一个快速的 gprof 指出 a=1 行需要大约 32% 的时间,而增量操作只需要大约 44% 的时间。因此,即使没有内存复制开销等,这个简单程序的可用加速也非常适中。

标签: cuda fortran


【解决方案1】:

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

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

[此答案已从 cmets 组装并添加为社区 wiki 条目,以将此问题从 CUDA 标签的未回答列表中删除]

【讨论】:

    猜你喜欢
    • 2021-03-21
    • 1970-01-01
    • 1970-01-01
    • 2013-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 2020-12-09
    相关资源
    最近更新 更多