问题
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:
- From Java I invoked a kernel using
forEach_kernel()
and that was not blocking - I had to add an extraAllocation.copyTo()
so that I could use the result. Was there another way? - 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?
- 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 callscript.forEach_kernel()
?
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/21358689/renderscript-blocking-function-invokation