Memory management 在OpenCL中写入本地内存会使内核速度降低400%?

Memory management 在OpenCL中写入本地内存会使内核速度降低400%?,memory-management,opencl,Memory Management,Opencl,我有一个非常复杂的内核,我一直在优化它。在不阅读所有代码的情况下,有一个内核将一些值写入全局内存 然后,第二个内核启动并对该数据进行数十亿次计算,全部在本地内存中。我对代码进行了反复优化,使内核运行时间降低到大约275ms 内核的最后一部分在本地内存中处理的数据数组上循环,并搜索匹配的字符串。显然,如果找到匹配项,它需要让宿主程序知道这一点。为此,我将全局_数组[0].x更改为999,并将全局_数组[0].y更改为等于找到的结果 内核完成后,它读取全局_数组的第一个元素,检查.x==999,以及

我有一个非常复杂的内核,我一直在优化它。在不阅读所有代码的情况下,有一个内核将一些值写入全局内存

然后,第二个内核启动并对该数据进行数十亿次计算,全部在本地内存中。我对代码进行了反复优化,使内核运行时间降低到大约275ms

内核的最后一部分在本地内存中处理的数据数组上循环,并搜索匹配的字符串。显然,如果找到匹配项,它需要让宿主程序知道这一点。为此,我将全局_数组[0].x更改为999,并将全局_数组[0].y更改为等于找到的结果

内核完成后,它读取全局_数组的第一个元素,检查.x==999,以及我们是否知道找到了目标

在进行更多优化的过程中,我发现如果我注释掉全局_数组[0]=行,内核的运行速度将是原来的4倍,大约为62毫秒。知道全局内存很慢,我开始测试各种东西。我想,嘿,也许如果我改变本地数组,那么在最后做一个工作组拷贝回全局,我会得到一点速度提升

但是没有。。。我不知道。这让人很困惑。如果在内核的末尾,我将任何东西写入全局或本地内存中的任何位置,那么我的内核运行速度为270ms。如果我将相同的数据写入一个私有变量,或者只编写其他不相关的代码,则为62ms

我需要以某种方式从内核返回一个结果——但出于某种原因,写入一个局部变量,这是内核在结束前不减速地执行50倍的操作,当写入结束时,它似乎会疯狂地减速


有人能解释为什么会发生这种情况吗?我被难住了。

当您不向全局内存进行写操作时,JIT编译器很可能会将您的大部分代码检测为死代码,并将其删除。

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

您能发布您的内核代码吗?可能是Aah的重复。。。因此,仅仅通过计算,而从不实际返回某些内容或“显示”我对所做的工作做了任何事情,编译器基本上跳过了实际的工作?所以当我输入任何类型的返回值时,它看到它的功被使用了,所以它真的这样做了吗?有道理。如果对结果不做任何处理,就没有理由做这项工作。有人能证实这一点吗?(在离开之前,我想知道“很可能是”)你可以自己确认这一点。保留对全局内存的写入,但用常量替换复杂的计算。如果您想查看是否有差异,请尝试使用本地和全局内存。