例如,nVidia 有 CUBLAS,它承诺加速 7-14 倍。天真地,这远不及任何 nVidia 的 GPU 卡的理论吞吐量。在 GPU 上加速线性代数有哪些挑战,是否已经有更快的线性代数路由可用?
GPU 系统上 BLAS/LAPACK 或其他线性代数例程的最快可用实现是什么?
就其他实现而言,我无法回答您问题的后半部分,但我可以就挑战提供一些见解。作为参考,我个人在具有 2GB 内存的 nVidia GTX 560 Ti 上使用了 ViennaCL 作为我的基准测试。
通过中档 i5 上的串行代码,我看到密集矩阵乘法的速度提高了大约 40 倍。对于诸如向量标量乘法之类的操作,我看到了高达 1000 倍的加速。然而,房间里 800 磅重的大猩猩是内存带宽。对于大多数商业 GPU,您将使用诸如 PCIe 之类的东西,它将您的吞吐量限制在大约 6GB/s。在我的例子中,虽然计算速度快了 40 倍,但三个矩阵副本(两个到 GPU,一个返回)每个所花费的时间都与在 CPU 上进行计算所花费的时间差不多。
任何用于 GPU 线性代数的通用库的问题将是它们无法真正重用 GPU 上的对象,因为它们不知道您将如何处理它们。因此,每次调用计算内核都可能需要复制到 GPU,然后将结果复制回来。这将吞噬大部分收益。
如果您可以重用诸如矩阵之类的对象,那么您可以编写更高级别的算法来避免尽可能多的内存管理,但是库很难有效地做到这一点。
我希望这会有所帮助,我相信这里还有其他人在这方面更有经验,但这些是我在短暂涉足 GPU 计算期间获得的经验和印象。
让我只关注 CUDA 和 BLAS。
主机 BLAS 实现的加速不是评估吞吐量的好指标,因为它取决于太多因素,尽管我同意加速通常是人们关心的。
如果您查看NVIDIA 发布的基准测试并考虑到 Tesla M2090 具有 1331 Gigaflops(单精度)和 665 Gigaflops(双精度)峰值性能,您会发现对于 SGEMM 和 DGEMM,我们测得的吞吐量几乎为理论值的60%,相当不错。
但是你如何定义翻牌的表现呢?触发器计数/经过的时间,其中触发器计数为(和是矩阵维度),经过的时间可以包括或不包括从主机到 GPU 内存并返回的传输时间。(正如戈德里克正确指出的那样,这有很大的不同!)
至于持续浮点吞吐量,我认为应该在不考虑数据和结果传输时间的情况下计算触发器,这使得加速比较变得困难。此外,您必须考虑矩阵大小,因为最佳性能适用于大矩阵。
底线:实际应用程序的加速可能与线性代数例程的峰值测量性能有很大不同,因为您必须考虑 GPU 初始化、数据传输时间等。
所以我不会回答你关于最快库的问题,因为除非定义了精确的指标和问题,否则这个问题毫无意义。综上所述,我认为cuBLAS和MAGMA是一个很好的起点。