iOS Metal 计算管道比搜索任务的 CPU 实现慢

标签 ios performance shader metal

我做了一个简单的实验,通过在 CPU 和 GPU(使用 iOS8 Metal 计算管道)上实现搜索 1.000.000 行每行 50 个字符(5000 万字符映射)的朴素字符搜索算法。

CPU 实现使用简单的循环,Metal 实现给每个内核 1 行来处理(下面的源代码)。

令我惊讶的是,Metal 实现平均比简单的线性 CPU(如果我使用 1 个内核)慢 2-3 倍,如果我使用 2 个内核(每个内核搜索一半的数据库)则慢 3-4 倍! 我尝试了每组不同的线程(16、32、64、128、512),但仍然得到非常相似的结果。

iPhone 6:

CPU 1 core:  approx 0.12 sec
CPU 2 cores: approx 0.075 sec
GPU: approx 0.35 sec (relEase mode, validation disabled)

我可以看到 Metal 着色器花费了 90% 以上的内存访问(见下文)。

可以做些什么来优化它?

任何见解都将不胜感激,因为互联网上没有太多资源(除了标准的 Apple 编程指南)提供有关内存访问内部结构和特定于 Metal 框架的权衡的详细信息。

Metal 实现细节:

主机代码要点: https://gist.github.com/lukaszmargielewski/0a3b16d4661dd7d7e00d

内核(着色器)代码: https://gist.github.com/lukaszmargielewski/6b64d06d2d106d110126

GPU 帧捕获分析结果:

enter image description here

最佳答案

GPU 着色器也在内存中垂直移动,而 CPU 则水平移动。当您读取 charTable 时,请考虑在着色器中以锁步方式执行的每个线程实际或多或少同时触及的地址。如果转置 charTable 矩阵,GPU 可能会运行得更快。

此外,由于此代码以 SIMD 方式执行,每个 GPU 线程可能必须运行循环以达到完整的搜索短语长度,而 CPU 将利用早期输出。如果删除早期输出并保持代码简单,GPU 代码实际上可能会运行得更快一些。很大程度上取决于搜索词组的长度和匹配的可能性。

关于iOS Metal 计算管道比搜索任务的 CPU 实现慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30445801/

相关文章:

ios - IPA文件提取

ios - 如何阻止禁用的 UIbutton 执行点击操作

R 效率挑战 : Splitting a long character vector

linux - 在运行网络服务器或数据库的 Linux 服务器上应该监视哪些资源

javascript - Chrome 性能 : "standard" property names vs. 非标准

OpenGL - 顶点着色器颜色未传递给片段着色器

iphone - 当 HUD 显示之前显示警报时,为什么 MBProgressHUD 不显示?

ios - NSNumberFormatter 在 Xamarin.iOS + ShinobiChart 中返回 null

opengl - 非单调深度缓冲区; OpenGL 中的循环重叠

glsl - 将渲染屏幕作为(反馈-)纹理(Shadertoy)