我做了一个简单的实验,通过实现朴素字符搜索算法,在CPU和GPU (使用iOS8金属计算流水线)上搜索每50个字符的1.000.000行(50milcharmap)。
CPU实现使用简单循环,Metal实现给每个内核1行处理(下面的源代码)。
令我惊讶的是,金属实现平均要比简单的线性CPU慢2-3倍(如果我使用一个核心),如果我使用两个核心(每个内核搜索一半数据库),则要慢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%的访问内存(见下文)。
可以做些什么来优化它?
任何见解都将受到赞赏,因为在互联网上没有太多的信息来源(除了标准的苹果编程指南),它提供了有关内存访问内部和特定于金属框架的权衡的详细信息。
金属实现详细信息:
主机代码要点:https://gist.github.com/lukaszmargielewski/0a3b16d4661dd7d7e00d
内核(着色)代码:https://gist.github.com/lukaszmargielewski/6b64d06d2d106d110126
GPU帧捕获分析结果:

发布于 2016-06-18 17:01:04
GPU着色器也是垂直跨过内存,而CPU是水平移动。考虑到在读取charTable时,每个线程在着色器中以锁步方式执行的地址实际上或多或少地被同时执行。如果您的charTable矩阵被转换,GPU可能会运行得更快。
另外,由于这段代码是以SIMD方式执行的,所以每个GPU线程可能必须运行循环到完整的搜索短语长度,而CPU则可以利用早期退出。如果删除早期退出并保持代码简单,GPU代码实际上可能运行得更快一些。这在很大程度上取决于搜索短语的长度和匹配的可能性。
发布于 2015-06-03 18:48:45
我也要猜测,gpu没有被优化,因为它没有预测分支(可能都会执行),尝试以更线性的方式重写算法,而不带任何条件,或者将它们减少到最小值。
https://stackoverflow.com/questions/30445801
复制相似问题