我做了一个简单的实验,通过实现简单的字符搜索算法在 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 帧捕获分析结果: