Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. The general question is: which situations block the code and allow RenderScript to finish. 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. 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. What conditions result in this - maybe only when working on the same allocation?
  3. Will the invokable functions block a) each other, b) kernel? 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()?
like image 599
frangulyan Avatar asked Jan 26 '14 01:01

frangulyan


2 Answers

My experiments showed that even though the functions are invoked asynchronously on Java level, they are executed one after another in 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. This was not so obvious from the documentation. The third line will block until everything is finished.

like image 22
frangulyan Avatar answered Oct 23 '22 04:10

frangulyan


1) You could use rs.finish() to make sure you wait for the kernel to finish. Kernel execution is indeed asynchronous in 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). In this case, your second kernel won't start running until the first kernel completes.

3) Invokable functions (i.e. things you run with invoke_*() from Java) are not asynchronous. You will block until they complete on the Java side. 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. Those get run once when the ScriptC is created.

like image 106
Stephen Hines Avatar answered Oct 23 '22 03:10

Stephen Hines