Search code examples
javac++cjava-native-interface

Multiple java threads using native interface vs single java thread for multi threaded native


Im preparing for a project using JNI to accelerate some calculations for physical modeling. Native part does the calculations on a group of arrays each having more than 10M elements.

Question: Which option would be more suitable for performance:

1) Using 8 threads in java each working on 1/8 part of arrays through a native call(jni-->c++). Do I need to crop whole array into smaller arrays to prevent unnecessary array copying?

2) Using single thread in java that calls a native which is 8-threaded (pthreads?) Can I use pointer arithmetics to select only the necessary part to use in a thread?

I need to work on a single copy(or original) of arrays, does a c++ thread copy the whole array for itself? What about java thread? Which one isnt copying, I will use that one.

Note: Im using GetPrimitiveArrayCritical() to prevent array copying(working on original) of JNI interface. Calculations take long enough that JNI overhead can be neglected.

GetPrimitiveArrayCritical() pins the java array so GC stops working until native function releases it, does this affect other java threads accesibility?

Actually all is in a extern "C" if it is important .

OS: 64 bit windows7 CPU: fx8150 jvm: 64 bit GCC: 64 bit

Thanks.


Solution

  • From a design perspective, I would prefer approach #1 because it means that you don't have to manage threads in your JNI code. This adheres to the "single responsibility principle": your native code only needs to change if your algorithm changes. I also think that the facilities (threadpools and futures) that Java provides are easier to use than direct threads.

    However, if you do this you should pay particular attention to the warning about pinning and unpinning arrays from multiple threads.

    A better approach IMO is to allocate a direct ByteBuffer, and access it from JNI using GetDirectBufferAddress. This would let you use a Java-side threadpool to manage the work, and would eliminate any native-side concerns about buffer copies.