对于固定数据大小,双精度CUDA代码比单精度CUDA代码更快

时间:2013-09-08 15:52:46

标签: c++ performance cuda

我已经在CUDA中实现了一个算法,看起来它的运行速度比双精度要快,而不是单精度。

我知道通常单精度在GPU中更快。我的GPU是Nvidia Geforce GT 650M。

算法伪代码如下:

for k to numIterations
    for j to numRowsOfAMatrix
        CUDAmemset(double arrayGPU)
        CUBLASdotproduct(double arrayGPU,double arrayGPU) [using cublasDdot]
        CUBLASdotproduct(double arrayGPU,double arrayGPU) [using cublasDdot]
        CUBLASscalarVectorMultiplication(scalarCPU,double arrayGPU) [using cublasDaxpy]
        CUBLASvectorSum(double arrayGPU,double arrayGPU) [using cublasDaxpy]
    end
end 

我使用以下属性运行了一些测试:数组长度为2500。矩阵行长度是2700。

我获得的时间如下:

50次迭代:

单个

的20.9960秒

双倍

20.1881秒

200次迭代:

81.9562秒单身

双倍

78.9490秒

500次迭代:

单个

的199.661秒 双击

199.045秒

1000次迭代:

单个

413.129秒 双打

396.205秒

任何想法为什么双精度更快?

2 个答案:

答案 0 :(得分:4)

我不相信你可以说双精度版本比单精度版本更快。您自己的时间显示50次迭代大约需要20秒,500次迭代大约需要200秒。那么问题就变成了原因?

对我来说,看起来你的代码主要是API和PCI-e总线延迟。在这种情况下,即使是单精度和双精度之间的两倍内存带宽差异也可能无关紧要。如果每个数组只有大约2500个长度,那么与总执行时间相比,计算的算术和设备存储器事务部分将是绝对微小的。

查看您的伪代码可以显示原因。在每次迭代时,两个点调用都会启动一个或多个内核,等待它们完成,然后从设备下载标量结果。然后必须将标量上传到设备进行每次axpy调用,然后启动内核。根据注释中的信息,这意味着您的代码每个输入行可能执行两个阻塞内存副本和六个内核启动,每次迭代有2700个输入行。这意味着您的代码每次迭代执行 10-15,000 GPU API调用,这是很多事务和API延迟(特别是如果您在WDDM Windows平台上执行此操作)每行几千FLOP和几十kb的GPU内存访问。

在这种情况下,GPU的峰值单精度比双精度算术吞吐量高12倍这一事实无关紧要,因为计算时间是您测量的总挂钟时间的一小部分。

答案 1 :(得分:1)

两种算法(在您的情况下,单精度和双精度版本)之间的计算成本差异通常通过渐近计算复杂度来衡量。因为talonmies(延迟)解释的原因,双精度可以与固定(小的,在你的情况下)矢量长度中具有与单精度相同的性能,这并不奇怪。要真正说明哪种算法更快,您应该根据向量长度N分析时间,从小到大的N值开始。

另一个与GPGPU无关的例子是FFT,它具有O(NlogN)的渐近复杂度,然后比DFT的“强力”求和更方便,如{{1}复杂性。但是,如果将FFT与“强力”DFT求和之间的时序与非常低的O(N^2)值进行比较,您会发现“强力”DFT求和将花费最少的时间。