简体   繁体   English

RenderScript阻塞函数调用

[英]RenderScript blocking function invokation

I am new to RenderScript and still have not so good idea on blocking/non-blocking nature of the calls from Java layer. 我是RenderScript的新手,对Java层调用的阻塞/非阻塞性质仍然不太了解。 The general question is: which situations block the code and allow RenderScript to finish. 一般问题是:哪些情况会阻止代码并允许RenderScript完成。 Particularly: 尤其:

  1. From Java I invoked a kernel using forEach_kernel() and that was not blocking - I had to add an extra Allocation.copyTo() so that I could use the result. 从Java我使用forEach_kernel()调用内核并且没有阻塞 - 我不得不添加额外的Allocation.copyTo()以便我可以使用结果。 Was there another way? 有另一种方式吗?
  2. I read somewhere that if there are 2 kernels then calling second will block until the first one will finish. 我读到某个地方,如果有2个内核,那么调用第二个将阻塞,直到第一个完成。 What conditions result in this - maybe only when working on the same allocation? 导致这种情况的原因 - 可能只有在进行相同的分配时?
  3. Will the invokable functions block a) each other, b) kernel? 可调用函数会阻塞a)彼此,b)内核吗? Particularly, I have a custom initializer invokable function which I need to prepare some data which will be later used by the kernel. 特别是,我有一个自定义初始化程序可调用函数,我需要准备一些稍后将由内核使用的数据。 This preparation might take some time so I would like to know if it is dangerous to call in Java script.invoke_somefunc() and then immediately call script.forEach_kernel() ? 这个准备可能需要一些时间,所以我想知道调用Java script.invoke_somefunc()然后立即调用script.forEach_kernel()是否危险?

1) You could use rs.finish() to make sure you wait for the kernel to finish. 1)您可以使用rs.finish()来确保等待内核完成。 Kernel execution is indeed asynchronous in RS. 内核执行在RS中确实是异步的。

2) We only allow one kernel to execute at a time (ignoring ScriptGroup, where you have a DAG of kernels, and thus maybe some additional room for optimizations). 2)我们一次只允许一个内核执行(忽略ScriptGroup,你有一个内核的DAG,因此可能有一些额外的优化空间)。 In this case, your second kernel won't start running until the first kernel completes. 在这种情况下,第二个内核在第一个内核完成之前不会开始运行。

3) Invokable functions (ie things you run with invoke_*() from Java) are not asynchronous. 3)Invokable函数(即从Java调用_ *()运行的东西) 不是异步的。 You will block until they complete on the Java side. 您将阻止它们在Java端完成。 Thus, they will block each other, or kernels. 因此,它们会相互阻塞,或者内核。 If you have a kernel followed by an invoke, you will asynchronously start the kernel, but the invoke won't begin until the kernel finishes. 如果你有一个内核后跟一个调用,你将异步启动内核,但是在内核完成之前调用才会开始。 You will then be waiting for the invoke to finish as well. 然后,您将等待调用完成。

One more detail. 还有一个细节。 If your initializer doesn't require parameters, you can put it in an actual "void init(void)" function. 如果初始化程序不需要参数,则可以将其置于实际的“void init(void)”函数中。 Those get run once when the ScriptC is created. 那些在创建ScriptC时运行一次。

My experiments showed that even though the functions are invoked asynchronously on Java level, they are executed one after another in RenderScript. 我的实验表明,即使函数在Java级别上异步调用,它们也会在RenderScript中一个接一个地执行。 So basically having: 所以基本上有:

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

will return immediately from first 2 lines but on RenderScript level kernel will not start until somefunc is finished. 将从前两行立即返回,但在RenderScript级别kernel将不会启动,直到somefunc完成。 This was not so obvious from the documentation. 从文档中可以看出这一点并不明显。 The third line will block until everything is finished. 第三行将阻止,直到一切都完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM