RenderScript是否支持本地线程同步?

3
在一个最近的SO问题中,我解释了如何多次调用RenderScript内核将有效地强制所有线程在调用之间全局同步。
我目前正在处理应用于图像数据的多个卷积。由于卷积算法需要读取输入图像周围的像素数据,因此我实现了一个工作流,在其中多次调用自定义内核--以确保在每个步骤中,前一个卷积的所有数据都已准备好并在正确的坐标处可用。到目前为止,这种技术对我非常有效。
然而,在不断追求优化的过程中,我注意到通过将中间值保留在本地寄存器中,而不是在内核调用之间将它们写回全局内存分配,可以获得更高的性能。如果我能以这种方式链接这些卷积,事情会运行得更快。显然,问题在于访问周围线程的寄存器实际上是不可能的。此外,这将要求线程同步运行,以确保在阶段之间计算这些中间值的预期顺序。
在CUDA和OpenCL中,这些问题非常普遍,并且通过众所周知的屏障同步+共享内存平铺技术得到解决,这反过来又依赖于CUDA线程块或OpenCL工作组的概念。我认为这些概念在RenderScript中不存在,因为这个问题与桌面级GPU和移动SoC之间极为不同的体系结构密切相关。
因此,我显而易见的问题是,这样的事情在RenderScript中是否可能?也就是说,更好地管理线程,可能的线程组,以便更快地在它们之间共享数据。
在Jason Sams和Tim Murray的Google I/O 2013 RenderScript talk中讨论了脚本组如何进行一些幕后优化,例如跨设备并行化、内存平铺和内核融合;通过在组中运行时分析依赖DAG,并在需要时自动创建分配或可能优化它们。我假设最后一部分是指融合内核,使它们可以处理自己的本地数据,有点像我上面提到的将数据保存在本地寄存器中,并将单独的步骤组合在一个内核中。
所有这些似乎非常符合我的要求,特别是因为我的应用确实是一个明确定义的相互依赖操作的DAG(用于卷积神经网络)。因此,如果脚本组确实是这些机制的可行移动替代品,我想知道是否有任何影响这些优化发生的方式和位置的方法。或者如果没有,那么在特定情况下(卷积算法的“周围”像素数据访问),运行时可以信任多少从我的数据依赖性中推断出正确的结论,考虑到它所运行的硬件。
我意识到这可能仍然是一个正在进行的工作,而方法在这一点上高度依赖于硬件。因此,如果目前没有针对这些问题的直接解决方案——我非常愿意接受RenderScript在未来版本中可能如何处理这种工作流程的推测答案。
如果您能提供有关此事的见解,我将不胜感激,因为这将极大地影响我的项目发展方向,更不用说肯定还有许多其他人想知道如何处理RS中的此类通用并行计算任务。
非常感谢!
1个回答

3
正如你已经发现的那样,RS中没有直接在线程之间共享数据的方法。但是,您所描述的可以使用ScriptGroup来实现。问题在于组中的每个脚本必须是唯一的,因此您不能重复提供相同的脚本。至少目前不可以。您可以将脚本的“核心”放在RS标题中,并从多个内核中包含它。 ScriptGroup允许您将一个脚本的输出成为另一个脚本的输入,或者将一个脚本的输出变为另一个脚本的全局字段。文档指出,内核到内核(输出到输入)是更有效的用例。使用这种方法,您的同步问题将得到解决,因为引擎将对整个输入数据集执行第一个脚本,然后再开始执行第二个脚本等等。脚本本身将根据硬件适当地并行化(使用CPU或GPU / DSP)。引擎不必在脚本之间弹回到Java,并且如果需要,还可以在幕后管理数据分配。
您可能会注意到的是,ScriptGroup利用Script.KernelID或Script.FieldID来标识要连接两个内核的确切脚本或字段。只要您明确调用您的内核函数并使用RS编译器属性指示符自动生成这些东西,就可以为自定义脚本生成它们。然后,您可以调用getKernelID_ (其中'name'是脚本中的内核函数名称)来获取内核ID。

没错,脚本组绝对是解决这个问题的方法。我没有意识到它们只能与唯一的脚本一起使用,但我想这毕竟是DAG结构的要求,否则图中会有循环回到相同的脚本,完全扰乱了事情。好的,听起来不错,所以我会尝试一下,并进一步调查其性能如何。顺便说一句,我想提一下你的AnDevCon RenderScript演讲是我几个月前第一次观看时帮助我更好地理解RS的无价资源。谢谢! - monoeci
希望这能解决你正在处理的优化问题。感谢反馈,我很感激! - Larry Schiefer
2
最终,唯一脚本的限制将被解除,并且ScriptGroup将支持附加功能(调用,字段传播等)。此外,我们显然还在为SG后端进行更多的编译器优化,并与供应商合作确保其驱动程序正确执行。 - Tim Murray
@TimMurray,有没有可能公开一些关于OEM所需的驱动程序和内部层的额外文档? - Larry Schiefer
是的,我们正在处理这个问题。这需要一些时间。不过,所有驱动程序需要连接的东西都在AOSP中,所以如果你想知道驱动程序需要做什么,frameworks/rs/driver是一个很好的查找位置。 - Tim Murray
非常感谢您的更新。我之前在准备AnDevCon演讲时也了解过这方面的内容,但没有添加任何内容。我可能会在即将到来的AnDevCon上添加关于NDK使用RS的演示。我还想了解更多信息,以便协助我的客户开发新平台(即OEM)。非常感谢! - Larry Schiefer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接