17

我对 GPU 编程很陌生,但由于我有一项计算密集型任务,我转向 GPU 以获得可能的性能提升。

我尝试用ArrayFire 免费版重写我的程序。它确实比我启用多线程的 CPU 例程快,但没有达到我预期的程度(即 < 100% 加速),并且返回的结果不太正确(与 CPU 例程相比,误差 < 1%,假设CPU 例程的结果是正确的)。

我的任务主要是对大型矩阵(300MB-500MB 大小)进行元素方式的 float-32 数学运算,很少有 if-thens/switch-cases 等。我猜性能瓶颈可能是 CPU 和 GPU 内存之间的带宽,因为有大量数据读取等。我测试的 GPU 是 GeForce 580GTX,具有 3GB 显存。

如果我编写原始 CUDA 代码(使用 CUBLAS 等和平均优化)而不是使用 ArrayFire 来完成我的任务,是否还有很大的优化空间?我阅读了一些 NVIDIA 优化指南;似乎有一些内存访问技巧可以加快数据访问速度并减少银行冲突。ArrayFire 是否自动使用这些通用技巧?

4

1 回答 1

22

谢谢你的帖子。很高兴听到初步结果正在加速。我在 ArrayFire 工作,可以在这里回答您的问题。

首先,任何人都需要代码来帮助具体化。你能分享你写的代码吗?

其次,您应该按照以下方式考虑 CUDA 和 ArrayFire:CUDA 是一种对 GPU 进行编程的方法,它使您能够编写任何您想要的 GPU 代码。但是,幼稚的 CUDA 代码(通常比 CPU 慢)和专家级的、耗时的、手动优化的 CUDA 代码之间存在巨大差异。ArrayFire(以及其他一些 GPU 库,如 CUBLAS)已经投入了许多人年的优化,并且通常会提供比大多数普通人有时间自己实现的更好的结果。但是,人们使用 ArrayFire(或其他库)的程度也存在差异。在使用 ArrayFire 库调用时可以而且应该调整一些变量以获得最佳性能。如果您发布代码,我们可以帮助在这里分享其中的一些。

第三,ArrayFire 在依赖 BLAS 的函数中使用了 CUBLAS,所以直接使用 CUBLAS 不太可能有太大区别。

第四,是的,ArrayFire 使用了 NVIDIA CUDA 编程指南中提供的所有优化(例如更快的数据传输和减少内存库冲突,就像你提到的那样)。这就是 ArrayFire 开发的大部分重点,优化这些事情。

最后,您注意到的数据差异可能是由于 CPU 与 GPU 计算的性质所致。由于它们是不同的设备,您经常会看到略有不同的结果。并不是 CPU 比 GPU 提供更好的结果,而是它们都以稍微不同的方式以有限的精度工作。如果您使用单精度而不是双精度,您可能会考虑这一点。发布代码也可以让我们帮助解决这个问题。

发布代码后,很高兴扩展我的答案。

于 2012-09-29T23:06:16.380 回答