我是 GPU 编程的新手,并试图首先确定特定产品是否值得移植到 GPU。算法中的一个主要步骤需要计算大量Frobenius 乘积(类似于点积,但在矩阵上——逐元素乘法,然后对乘积求和。)
数据结构使我可以将所有内容存储在 GPU 的全局内存中,但不能存储在共享内存中。我的理解是,当算术强度(每传输字节的浮点运算)很高时,GPU 表现最好,而点积在这方面表现(相对)较差。我试图弄清楚有多糟糕,并且对一些细节感到困惑。
为了使事情具体化,让我们假设我有 64x64 的双精度条目矩阵。(它们必须是双精度的。)让我们假设矩阵的布局使得它们也正确对齐。显然,即使每个 SM 一个块,这也太大而无法存储在共享内存中。所以我的想法是“平铺”问题并在每个块中存储每个矩阵的 16x16 平铺;现在我至少可以一次对所有八个块进行操作,为每个产品分配一个线程,计算每个块中的总和,等等。
我的问题是:
1) FLOPS/byte 到底是什么意思?或者更准确地说,在这种情况下,双精度乘法需要多少 FLOPS?如果答案是 1,那么似乎我为每个操作移动了 16 个字节,这看起来很糟糕。
2) 这个计算是在合并内存读取的上下文中完成的吗?合并是帮助我还是伤害我?
还有一个更模糊的问题:
3)这甚至值得做吗?
作为参考,我可以使用 GTX 580 进行基准测试和实验,以及 CUDA 4.2,尽管如果有帮助的话我可能会安装 5.0。如果最近的 Nvidia 架构在某些方面更友好,那么了解这也很有用,尽管我可能无法访问其中一个。
更新:
我仍在研究整个算法,但我有充分的理由相信可以生成矩阵并将其保存在 GPU 的全局内存中,而无需向 CPU 移动任何东西。
我可能不得不重新检查我可以确保合并内存访问的假设。一些矩阵是四维对象的切片;大约 3/4 的矩阵自然会以明显的合并方式访问,而其他 1/4 则不是。我可以通过两次存储大对象来解决这个问题,但这会产生一个新问题:
4) 合并内存准则是否也适用于从共享内存移回全局内存?