【问题标题】:RenderScript blocking function invokationRenderScript 阻塞函数调用
【发布时间】:2014-01-27 02:30:46
【问题描述】:

我是 RenderScript 的新手,但对于来自 Java 层的调用的阻塞/非阻塞性质仍然不太了解。一般的问题是:哪些情况会阻塞代码并允许 RenderScript 完成。特别是:

  1. 从 Java 中,我使用 forEach_kernel() 调用了一个内核,这并没有阻塞 - 我必须添加一个额外的 Allocation.copyTo() 以便我可以使用结果。还有其他方法吗?
  2. 我在某处读到,如果有 2 个内核,则调用第二个内核将阻塞,直到第一个内核完成。什么条件会导致这种情况 - 可能仅在处理相同分配时?
  3. 可调用函数会阻塞 a) 彼此,b) 内核吗?特别是,我有一个自定义初始化程序可调用函数,我需要准备一些数据,稍后将由内核使用。这种准备可能需要一些时间,所以我想知道在 Java 中调用 script.invoke_somefunc() 然后立即调用 script.forEach_kernel() 是否危险?

【问题讨论】:

    标签: android renderscript


    【解决方案1】:

    1) 您可以使用 rs.finish() 来确保等待内核完成。内核执行在 RS 中确实是异步的。

    2) 我们一次只允许执行一个内核(忽略 ScriptGroup,您有一个 DAG 内核,因此可能还有一些额外的优化空间)。在这种情况下,您的第二个内核在第一个内核完成之前不会开始运行。

    3) 可调用函数(即您使用 Java 中的 invoke_*() 运行的东西)是异步的。您将一直阻塞,直到它们在 Java 端完成。因此,它们将相互阻塞,或内核。如果您有一个内核后跟一个调用,您将异步启动内核,但调用不会在内核完成之前开始。然后,您也将等待调用完成。

    更多细节。如果您的初始化程序不需要参数,您可以将其放入实际的“void init(void)”函数中。这些会在创建 ScriptC 时运行一次。

    【讨论】:

    • 谢谢,现在我清楚了。不幸的是,我的初始化函数需要分配本身作为参数 - 它正在创建一个summed area table 输入(我想不出一种并行化此任务的好方法,因此决定在一个线程中运行作为准备步骤),这将稍后被内核使用。
    • 是的,我们知道有很多理由进行单线程初始化(没有参数就无法完成)。这就是我们有调用函数的原因。
    • 这个答案已经有一段时间了。第 3 点仍然有效还是我误解了 Android 文档:“反射的 forEach、invoke、reduce 和 set 方法是异步的——每个方法都可能在完成请求的操作之前返回 Java。” developer.android.com/guide/topics/renderscript/compute.html
    【解决方案2】:

    我的实验表明,即使在 Java 级别上异步调用这些函数,它们也会在 RenderScript 中一个接一个地执行。所以基本上有:

    script.invoke_somefunc();
    script.forEach_kernel();
    alloc.copyTo(); // or rs.finish();
    

    将立即从前 2 行返回,但在 RenderScript 级别 kernel 将在 somefunc 完成之前开始。这在文档中并不那么明显。第三行将阻塞,直到一切完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-27
      • 1970-01-01
      • 1970-01-01
      • 2017-07-30
      • 1970-01-01
      • 2020-06-27
      相关资源
      最近更新 更多