我很想知道是否有任何常用算法(排序、搜索、图表等)已移植到 OpenCL(或任何 GPU 语言),以及性能与 CPU 执行的相同算法相比如何。我对结果(数字)特别感兴趣。
谢谢!
GPU 是高度专业化的硬件,旨在很好地完成一小组任务并高度并行化。这基本上是算术(特别是单精度浮点数学,尽管较新的 GPU 在双精度方面做得很好)。因此,它们仅适用于特定算法。我不确定排序是否适合该类别(至少在一般情况下)。
更常见的例子是金融工具的定价、大量的矩阵数学,甚至破解加密(通过蛮力)。话虽如此,我确实找到了使用混合算法进行快速并行 GPU 排序。
另一个常见的例子是在 Nvidia GPU 上运行 SETI@HOME,但它是在比较苹果和橘子。与 CPU 通常所做的工作相比,GPU 的工作单元是不同的(并且非常有限)。
看看推力:
Thrust 是一个 CUDA 并行算法库,其接口类似于 C++ 标准模板库 (STL)。Thrust 为 GPU 编程提供了一个灵活的高级接口,极大地提高了开发人员的工作效率。
小心,非常小心为 GPGPU 引用的任何性能数据。很多人喜欢发布非常令人印象深刻的数字,但没有考虑将输入数据从 CPU 传输到 GPU 以及返回输出数据所需的传输时间,两者都超过了 PCIe 瓶颈。
在 NVidia 的网站上有很多这样的例子。请记住,诸如排序之类的某些事情需要特殊算法来实现有效的并行性,并且可能不如单核上的非线程算法那么有效。
在许多接受图像上传的网站上,图像调整大小必须是常见的。
使用绝对最低质量选项和最近邻采样,在 C# 中调整 2600ish x 2000ish 2MB jpeg 图像(到 512x512)需要 23.5 毫秒。使用的功能是graphics.DrawImage()
基于一个。CPU 使用率也是 %21.5。
在 C# 端获取“rgba 字节数组”提取并将其发送到 GPU 并在 GPU 中调整大小并将结果返回到图像中需要 6.3 毫秒,CPU 使用率为 %12.7。这是通过仅 320 个内核的 %55 便宜的 gpu 完成的。
只有 3.73X 的加速倍数。
这里的限制因素是,将提取的 20MB rgb 数据(jpeg 只有 2MB!)发送到 GPU。该耗时部分几乎占总时间的 %90,包括 C# 端字节数组提取!所以我猜如果提取部分也可以在 GPU 中完成,至少会有大约 30 倍的加速。
30X还不错。
然后,您可以将提取层与调整大小层一起流水线化,以隐藏内存复制延迟,从而获得更快的速度!这可能是 40X-50X。
然后提高采样质量(例如双三次而不是最近邻),您在 GPU 方面更有优势。添加一个 5x5 高斯滤波器只增加了 0.77 毫秒。除此之外,CPU 会获得更长的时间,特别是如果所需的高斯参数与 C#.Net 实现不同时。
即使您对加速比不满意,卸载到 GPU 并在 CPU 上拥有“空闲内核”仍然有利于将更多工作推送到该服务器。
现在加上 GPU 功耗水平的事实(在这个例子中是 30W 对 125W),它更有优势。
CPU几乎赢不了
C[i]=A[i]+B[i]
当双方都在优化代码上运行并且您仍然可以将一半的数组卸载到 GPU 并同时使用 CPU+GPU 更快地完成时进行基准测试。
GPU 不是为非均匀工作而构建的。GPU 具有很深的管道,因此在由于分支而停顿后站起来需要很长时间。SIMD 类型的硬件也强制它在其上的所有工作项上做同样的事情。当一个工作项与组做不同的事情时,它会丢失轨道并在整个 SIMD 管道中添加气泡,或者只是其他人等待同步点。因此,在完全混乱的条件下,brancing 会影响深层和宽流水线区域,甚至比 CPU 还要慢。