在OpenCL中写入本地内存会使内核减慢400%?

时间:2015-08-04 18:25:23

标签: memory-management opencl

我有一个非常复杂的内核,我一直在优化。没有经过所有代码,就有一个内核将一些值写入全局内存。

然后第二个内核触发并对该数据进行数十亿次计算,所有计算都在本地内存中。我一遍又一遍地优化代码,使内核运行时间缩短到大约275毫秒。

内核的最后部分循环遍历在本地内存中处理的数据数组,并搜索匹配的字符串。显然,如果找到匹配,则需要让主程序知道这一点。我通过将global_array [0] .x更改为999并将global_array [0] .y更改为等于找到的结果来完成此操作。

在内核完成后,它会读取global_array的第一个元素,检查.x == 999是否如此,如果是,我们知道我们找到了目标。

在进行更多优化的过程中,我发现如果我注释掉了global_array [0] =行,则内核运行速度提高了4倍,大约为62毫秒。知道全局内存很慢,我开始测试各种各样的东西。我想,嘿,也许如果我更改了LOCAL数组,那么最后我将work_group_copy改回全局,我的速度会有所提高。

但不......我不。这让人感到困惑。如果在内核的末尾,我写任何东西看似在全局或本地内存中的任何位置,我的内核运行在270ms。如果我将相同的数据写入私有变量,或者只是执行其他不相关的代码,那么它就是62ms。

我需要以某种方式从内核返回一个结果 - 但由于某种原因,写入一个局部变量,内核在它没有减速到达结束之前做50倍的事情,似乎在写入时就像疯了一样减速结束。

任何人都可以解释为什么会这样吗?我很难过。

2 个答案:

答案 0 :(得分:1)

如果不写入全局内存,JIT编译器很可能会将大部分代码检测为死代码,并将其删除。

答案 1 :(得分:1)

要验证我们需要查看代码。您可以验证的一种方法是留在写出部分,但保护它的条件是您知道永远不会满足(但编译器无法知道 - 例如,某个包含特定值的全局地址) 。你也必须小心这一点,因为编译器可以执行代码动作来检查线程中较早的状态,以便仍然跳过工作。所以条件(永远不会满足)需要基于你做的一些实际工作的结果(或者有可能受到它的影响,或者足够复杂以至于编译器认为可能存在依赖) 。顺便说一下,我曾经写过用于测量gpg性能的OCL微基准测试,而这些东西是你早期学到的东西之一 - 它是一个不断的战斗试图欺骗编译器不优化你正在尝试测量的工作。