CUDA矩阵乘法的性能

Posted

技术标签:

【中文标题】CUDA矩阵乘法的性能【英文标题】:perfomance of CUDA matrix multiplication 【发布时间】:2015-02-03 22:54:43 【问题描述】:

如果你能帮我澄清一些关于 GPU 性能的细节,那就太好了,因为我已经在这里呆了好几个星期了。 此外,我很抱歉我的英语不好,但我会尽力解释这个问题。

那么,关于我的问题。 让我们看一下非常简单的程序——使用共享内存的密集矩阵乘法。 据我了解,Nvidia 在 cuda 编程指南中提供了其中一种实现(这里是链接): http://docs.nvidia.com/cuda/cuda-c-programming-guide/#shared-memory

很简单,相信熟悉CUDA的人都已经看过了。 但是让我们测量一下这个内核的性能(Gflops)。 使用“Nvprof”实用程序,我们可以测量一些指标来计算浮点运算的计数,并使用 cuda 事件我们可以测量内核的执行时间。

所以,对于方阵乘法(每个矩阵中有 2048x2048 个浮点元素),我们有 (1.7180e+10)/(0.054 * 10^9) Gflpos = 318 Gflops。

现在重要的是,我使用的是 GeForce GTX Titan 卡,单精度峰值性能约为 3.1 Tflops。因此,我们只达到了峰值性能的 1/10 左右,但我们已经使用了我在大学 CUDA 课程中知道的所有优化(共享内存、合并内存访问等)。 在这里我猜它是因为它是内存绑定问题,但据我所知这是不对的。例如 cuBlas(如果我是对的)SGEMM 函数达到峰值性能的 71% 左右。我当然知道达到 cuBlas 的性能非常困难,但为什么我连 1 Tflop 都达不到呢?

所以,问题是:

1) 我的推理是否正确?

2) 我什至无法达到峰值性能的一半的主要原因是什么?

3) 我还可以使用哪些其他优化? (在这里您所知道的一切都会非常有用 - 文章、建议等)

感谢您的关注!

【问题讨论】:

你熟悉Google Scholar吗?使用关键字“GPU”“CUDA”“GEMM”的简单查询产生了一系列关于高性能实现策略的文章。算法之外的其余性能部分是经过微调的手工汇编语言实现(这几乎适用于所有计算平台)。 请出示您的代码。就目前而言,在我看来,您的问题过于宽泛,无法得到明确的答案。有太多可能的地方可以在没有看到您的实施的情况下提出改进建议。 关于代码:我在谈论提高 nvidia 代码的性能,我已经提供了链接。当然我有自己的实现(快 1.4 倍),但我决定不在这里提供它,因为这不是我想要的加速,而且我希望避免谈论我自己的代码中可能出现的错误。所以让我们考虑一下我们想要加速 Nvidia 代码。 谢谢,我不知道谷歌学术,太好了。 你确定有办法多次使用 assembley 来改进程序吗?据我了解,我们必须从峰值性能的 1/10 跃升至峰值性能的 7/10。对我来说似乎不真实。此外,CUDA 是 C 风格的代码,它是低级的,非常接近汇编。或者有什么我不明白的,很抱歉我的愚蠢问题。 【参考方案1】:

看你提到的代码,该代码只是一个简单的解释示例,但实际上并不实用,因为它没有考虑其他优化因素。从此类示例中优化性能在我的学习经验中并不有效。

当然,你看不到 cuBlas 的源代码,但是很少有开源项目包括MAGMA 具有矩阵乘法的实际实现。 MAGMA 源代码中的 MAGMABLAS 文件夹包含其对 BLAS 的实现,这对我了解如何实际实现矩阵乘法很有帮助。

【讨论】:

非常感谢,我忘了MAGMA是开源的。如果开普勒有 GEMM 的实现,那将解决我的问题。 什么是块大小?你在使用阻塞算法吗?【参考方案2】:

我不确定这是否适用,但在使用共享内存时,存储库冲突会降低性能。这里有一个很好的解释:What is a bank conflict? (Doing Cuda/OpenCL programming)

【讨论】:

是的,谢谢您的回答。我知道它是什么,而且我确信我正在避免银行冲突。

以上是关于CUDA矩阵乘法的性能的主要内容,如果未能解决你的问题,请参考以下文章

CUDA做矩阵乘法如何计算所需显存

大型矩阵的 CUDA 矩阵乘法中断

CUDA 矩阵乘法优化

在 CUDA 的平铺矩阵乘法中访问矩阵作为其转置

使用 CUDA 进行矩阵乘法:2D 块与 1D 块

CUDA 平铺矩阵乘法解释