我已经在CUDA中实现了一个算法,它的运行速度似乎比单一精度快得多。
我知道在GPU中通常单精度更快。我的GPU是Nvidia Geforce GT 650米。
算法伪码如下:
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秒双倍
知道为什么双精度更快吗?
发布于 2013-09-08 16:33:29
我不相信你能说双精度版本比单精度版本快。您自己的计时显示,50次迭代大约需要20秒,500次迭代大约需要200秒。那么问题就变成了为什么?
在我看来,您的代码似乎主要是API和PCI总线延迟。在这种情况下,即使是单精度和双精度之间的两倍内存带宽差异也可能与此无关。如果每个数组只有2500长,那么与整个执行时间相比,计算的算术和设备内存事务部分将是绝对小的。
看看你的伪码说明了为什么。在每次迭代时,两个点调用启动一个或多个内核,等待它们完成,然后从设备下载一个标量结果。然后,对于每次axpy调用,必须将标量上传到设备上,然后启动内核。根据注释中的信息,这意味着代码可能执行两个阻塞内存副本,每个输入行执行6个内核启动,每次迭代有2700个输入行。这意味着您的代码每次迭代执行10-15 000个GPU API调用,这是很多事务和API延迟(特别是在WDDM Windows平台上这样做的话),每行只需执行几千次失败和几十kb的GPU内存访问。
在这种情况下,GPU的峰值单精度比双精度算术吞吐量高12倍这一事实与此无关,因为计算时间是您测量的总时钟时间的非常小的一部分。
发布于 2013-09-08 20:22:13
两种算法(在您的例子中,单精度版本和双精度版本)之间的计算成本差异通常由渐近计算复杂性来度量。对于固定的向量长度(在您的示例中是较小的)向量长度,双精度可以具有与单个精度相同的性能,这一点并不奇怪,原因可以用talonmies (延迟)解释。要真正说明哪种算法更快,您应该根据向量长度N分析时间,从小到大的N值开始。
另一个与GPGPU无关的例子是快速傅立叶变换,它的渐近复杂度为O(NlogN),比O(N^2)复杂度的“蛮力”求和更方便。但是,如果您比较了N的很低值的快速傅立叶变换和“蛮力”DFT求和的时间,你会发现“蛮力”DFT求和所花费的时间最少。
https://stackoverflow.com/questions/18685620
复制相似问题