【发布时间】:2015-08-07 08:59:53
【问题描述】:
我做了一个简单的实验,通过实现简单的字符搜索算法在 CPU 和 GPU 上搜索 1.000.000 行,每行 50 个字符(50 百万字符映射)(使用 iOS8 Metal 计算管道)。
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)
我可以看到金属着色器花费了超过 90% 的内存访问(见下文)。
可以做些什么来优化它?
任何见解都将不胜感激,因为互联网上没有很多资源(除了标准的 Apple 编程指南),提供有关 Metal 框架特定的内存访问内部和权衡的详细信息。
金属实施细节:
主机代码要点: https://gist.github.com/lukaszmargielewski/0a3b16d4661dd7d7e00d
内核(着色器)代码: https://gist.github.com/lukaszmargielewski/6b64d06d2d106d110126
GPU 帧捕获分析结果:
【问题讨论】:
-
不要粘贴代码截图。它们基本上没用...剪切和粘贴实际代码。
-
@MarcB 我用 github gist 替换了屏幕截图。希望没问题(正确格式化那段代码有很大的麻烦)。
-
我尝试的第一件事是将 searchPhrase 移动到设备内存中。 Apple 表示不要为数组使用常量空间。让我们知道这是否有任何作用。
-
@Jessy :更改为设备空间没有任何改变。更重要的是:我失去了使用 setBytes 设置着色器缓冲区的机会:(Apple 声称它更快,因为您不必创建
对象)。 -
有趣。我想相关文件需要大修。谎言!
标签: ios performance shader metal