Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS金属计算管道比CPU执行搜索任务慢_Ios_Performance_Shader_Metal - Fatal编程技术网

iOS金属计算管道比CPU执行搜索任务慢

iOS金属计算管道比CPU执行搜索任务慢,ios,performance,shader,metal,Ios,Performance,Shader,Metal,我做了一个简单的实验,通过在CPU和GPU(使用iOS8金属计算管道)上实现naive char search算法来搜索1.000.000行,每行50个字符(50 mil char map) CPU实现使用简单的循环,金属实现为每个内核提供1行处理(下面的源代码) 让我惊讶的是,金属实现平均比简单的线性CPU慢2-3倍(如果我使用1个内核),如果我使用2个内核(每个内核搜索数据库的一半)则慢3-4倍! 我用每组不同的线程(16、32、64、128、512)进行了实验,但仍然得到了非常相似的结果

我做了一个简单的实验,通过在CPU和GPU(使用iOS8金属计算管道)上实现naive char search算法来搜索1.000.000行,每行50个字符(50 mil char map)

CPU实现使用简单的循环,金属实现为每个内核提供1行处理(下面的源代码)

让我惊讶的是,金属实现平均比简单的线性CPU慢2-3倍(如果我使用1个内核),如果我使用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%的访问内存(见下文)

可以做些什么来优化它?

如果您有任何见解,我们将不胜感激,因为互联网上没有太多的资源(除了标准的苹果编程指南),提供了内存访问内部细节和金属框架特有的权衡

金属实施细节:

主机代码要点:

内核(着色器)代码:

GPU帧捕获评测结果:


我也会猜,gpu没有针对if/else进行优化,它不会预测分支(它可能同时执行这两个分支),尝试以更线性的方式重写算法,而不带任何条件,或者将它们减少到最小值。

gpu着色器也在内存中垂直移动,而CPU在水平移动。考虑到在读取字符时,在着色器中每一个线程都或多或少地实际接触到的地址。如果将图表矩阵转置,GPU可能会运行得更快


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

不要粘贴代码的截图。它们基本上没用。。。剪切并粘贴实际代码。@MarcB I将屏幕截图替换为github gist。希望没问题(很难正确格式化那段代码)。我要做的第一件事是将SearchPhase移动到设备内存中。苹果公司表示,不要为阵列使用固定空间。让我们知道这是否有用。@Jessy:更改到设备空间并没有改变任何事情。更重要的是:我失去了使用setBytes设置着色器缓冲区的机会:(苹果声称这更快,因为你不必创建对象)。很有趣。我想相关文件需要彻底检查。谎言!分析工具清楚地显示(在所附的屏幕截图上可见)这不是瓶颈。超过90%的时间用于内存访问。