cuda中的矩阵乘法

时间:2010-10-05 02:47:46

标签: cuda

说我想将两个矩阵相乘,50乘以50.我有2种方法来排列线程和块。

a)计算结果矩阵的每个元素的一个线程。所以我在线程中有一个循环乘以一行和一列。

b)每个乘法的一个线程。结果矩阵的每个元素需要50个线程。在完成乘法之后,我可以使用二进制缩减来对结果求和。

我不知道采取哪种方式,所以我拿了b。这不太理想。事实上它很慢。知道为什么吗?我的猜测是,有太多的线程,他们大部分时间都在等待资源,这是真的吗?

4 个答案:

答案 0 :(得分:4)

与高性能计算中的许多事情一样,理解性能的关键在于理解内存的使用。

如果你使用一个线程做一次乘法,那么对于那个线程,你必须从内存中提取两个数据,乘以它们,然后做一些logarthmic数量的加法。这是针对mult和add和bit的三次内存访问 - 算术强度非常低。好消息是,这种方式有许多线程值得完成,每个线程只需要一点点内存/寄存器,这对于占用很有用;但内存访问工作的比例很差。

执行一个点乘积方法的简单一个线程具有相同类型的问题 - 每个乘法需要两次内存访问才能加载。好消息是整个点产品只有一个存储到全局存储器中,并且你避免了二进制缩减,它不能扩展并且需要大量同步;不利的是,现在的线程越来越少了,至少你的(b)方法对你有效。

现在你知道每个内存访问应该有一些方法比这更多;对于平方NxN矩阵,有N ^ 3工作来进行乘法,但只有3xN ^ 2个元素 - 所以你应该能够找到一种方法,每2个内存访问进行多于1次计算。

CUDA SDK中采用的方法是最好的方法 - 将矩阵分解为切片,并使用(b)方法 - 每个输出元素一个线程。但关键在于线程的排列方式。通过从缓慢的全局存储器中拉入整个小子矩阵到共享存储器,并从那里进行计算,可以进行多次乘法并添加从内存中读取的每个数字。这种方法在许多应用中是最成功的方法,因为获取数据 - 无论是通过网络,还是来自CPU的主存储器,还是GPU的片外访问 - 通常需要比处理数据更长的时间。

NVidia的CUDA页面中的文档(特别是http://developer.nvidia.com/object/cuda_training.html)非常好地描述了他们的SDK示例。

答案 1 :(得分:3)

您是否查看了CUDA文档:Cuda Programming Model

此外,示例源代码:Matrix Multiplication

答案 2 :(得分:1)

你看了吗

$SDK/nvidia-gpu-sdk-3.1/C/src/matrixMul

即。 SDK中的矩阵乘法示例?

答案 3 :(得分:0)

如果您不需要自己实现,只需使用库 - CUBLAS,MAGMA等,提供调整矩阵乘法实现。