我很想知道是否有人通过使用例如nVidia CUDA编写了利用GPGPU的应用程序。如果是这样,您发现了哪些问题,与标准 CPU 相比,您获得了哪些性能提升?
10 回答
我一直在使用ATI 的流 SDK而不是 Cuda 进行 gpgpu 开发。您将获得什么样的性能增益取决于很多因素,但最重要的是数字强度。(即计算操作与内存引用的比率。)
BLAS level-1 或 BLAS level-2 函数(例如添加两个向量)仅对每 3 个内存引用执行 1 个数学运算,因此 NI 为 (1/3)。使用 CAL 或 Cuda 总是比仅在 cpu 上运行要慢。主要原因是将数据从 cpu 传输到 gpu 并返回所需的时间。
对于像 FFT 这样的函数,有 O(N log N) 次计算和 O(N) 次内存引用,因此 NI 为 O(log N)。如果 N 非常大,比如 1,000,000,那么在 gpu 上执行它可能会更快;如果 N 很小,比如 1,000,它几乎肯定会更慢。
对于 BLAS 3 级或 LAPACK 函数,如矩阵的 LU 分解,或寻找其特征值,需要 O(N^3) 次计算和 O(N^2) 次内存引用,因此 NI 为 O(N)。对于非常小的数组,假设 N 是几个分数,这在 cpu 上仍然会更快,但是随着 N 的增加,算法很快从内存限制到计算限制,并且 gpu 上的性能提升非常迅速地。
任何涉及复杂算术的计算都比标量算术多,这通常会使 NI 加倍并提高 gpu 性能。
(来源:earthlink.net)
这是 CGEMM 的性能——在 Radeon 4870 上完成的复杂单精度矩阵-矩阵乘法。
我写了一些简单的应用程序,如果你可以并行化浮点计算真的很有帮助。
我发现以下由伊利诺伊大学厄巴纳香槟分校教授和 NVIDIA 工程师共同教授的课程在我刚开始时非常有用:http: //courses.ece.illinois.edu/ece498/al/Archive/Spring2007/Syllabus.html(包括所有讲座的录音)。
我已经将 CUDA 用于几种图像处理算法。当然,这些应用程序非常适合 CUDA(或任何 GPU 处理范例)。
IMO,将算法移植到 CUDA 时有三个典型阶段:
- 初始移植:即使对 CUDA 有非常基本的了解,您也可以在几个小时内移植简单的算法。如果幸运的话,您的性能会提高 2 到 10 倍。
- 琐碎优化:这包括使用纹理输入数据和填充多维数组。如果您有经验,这可以在一天内完成,并且可能会使您的性能提高 10 倍。生成的代码仍然可读。
- 核心优化:这包括将数据复制到共享内存以避免全局内存延迟,将代码翻过来以减少使用的寄存器数量等。您可以在这一步花费数周时间,但性能提升并不值得大多数情况下。在这一步之后,您的代码将变得如此模糊,以至于没有人理解它(包括您)。
这与为 CPU 优化代码非常相似。然而,GPU 对性能优化的响应甚至比 CPU 更难预测。
我一直在使用 GPGPU 进行运动检测(最初使用 CG,现在使用 CUDA)和图像处理稳定化(使用 CUDA)。在这些情况下,我已经获得了大约 10-20 倍的加速。
根据我的阅读,这对于数据并行算法来说是相当典型的。
我已经在 CUDA 中实现了蒙特卡洛计算以用于某些财务用途。优化后的 CUDA 代码比“本可以更努力但不是真的”多线程 CPU 实现快约 500 倍。(此处将 GeForce 8800GT 与 Q6600 进行比较)。众所周知,蒙特卡洛问题是令人尴尬的平行问题。
遇到的主要问题包括由于 G8x 和 G9x 芯片对 IEEE 单精度浮点数的限制而导致的精度损失。随着 GT200 芯片的发布,这可以通过使用双精度单元在一定程度上缓解,但会牺牲一些性能。我还没试过。
此外,由于 CUDA 是 C 扩展,因此将其集成到另一个应用程序中并非易事。
我在 GPU 上实现了一个遗传算法,并获得了大约 7 的速度提升。正如其他人指出的那样,更高的数值强度可能会带来更多的收益。所以,是的,如果应用程序是正确的,收益就在那里
我已经实现了 Cholesky 分解,用于使用 ATI Stream SDK 在 GPU 上求解大型线性方程。我的观察是
性能加速高达 10 倍。
通过将其扩展到多个 GPU 来解决相同的问题以对其进行更多优化。
我编写了一个复值矩阵乘法内核,它在我使用它的应用程序中比 cuBLAS 实现高出约 30%,以及一种向量外积函数,它比其余的乘法跟踪解决方案运行几个数量级问题。
这是最后一年的项目。我花了整整一年的时间。
是的。我已经使用 CUDA api实现了非线性各向异性扩散滤波器。
这相当容易,因为它是一个过滤器,必须在给定输入图像的情况下并行运行。我在这方面没有遇到很多困难,因为它只需要一个简单的内核。加速大约是 300 倍。这是我在 CS 上的最后一个项目。该项目可以在这里找到(它是用葡萄牙语写的)。
我也尝试过编写Mumford&Shah分割算法,但是写起来很痛苦,因为 CUDA 还处于起步阶段,所以会发生很多奇怪的事情。if (false){}
我什至看到通过在代码 O_O 中添加 a 来提高性能。
这种分割算法的结果并不好。与 CPU 方法相比,我的性能损失了 20 倍(但是,由于它是 CPU,因此可以采用产生相同结果的不同方法)。它仍在进行中,但不幸的是我离开了我正在工作的实验室,所以也许有一天我可能会完成它。