简体   繁体   English

使用本机接口的多个java线程与用于多线程本机的单个java线程

[英]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. 我正在准备一个使用JNI加速物理建模计算的项目。 Native part does the calculations on a group of arrays each having more than 10M elements. Native部分对一组数组进行计算,每个数组都有超过10M的元素。

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++). 1)在java中使用8个线程,每个线程通过本机调用(jni - > c ++)处理1/8部分数组。 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? 2)在java中使用单线程调用8线程的本机(pthreads?)我可以使用指针算术来仅选择在线程中使用的必要部分吗?

I need to work on a single copy(or original) of arrays, does a c++ thread copy the whole array for itself? 我需要处理单个副本(或原始)数组,c ++线程是否为自己复制整个数组? What about java thread? 那么java线程呢? Which one isnt copying, I will use that one. 哪一个不复制,我会用那个。

Note: Im using GetPrimitiveArrayCritical() to prevent array copying(working on original) of JNI interface. 注意:我使用GetPrimitiveArrayCritical()来防止JNI接口的数组复制(原始工作)。 Calculations take long enough that JNI overhead can be neglected. 计算需要足够长的时间才能忽略JNI开销。

GetPrimitiveArrayCritical() pins the java array so GC stops working until native function releases it, does this affect other java threads accesibility? GetPrimitiveArrayCritical() java数组,因此GC停止工作,直到本机函数释放它,这会影响其他Java线程可访问性吗?

Actually all is in a extern "C" if it is important . 实际上,如果重要的话,所有人都在extern "C"

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

Thanks. 谢谢。

From a design perspective, I would prefer approach #1 because it means that you don't have to manage threads in your JNI code. 从设计的角度来看,我更喜欢方法#1,因为这意味着您不必管理JNI代码中的线程。 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. 我还认为Java提供的工具(线程池和期货)比直接线程更容易使用。

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 . 更好的方法IMO是分配直接的 ByteBuffer ,并使用GetDirectBufferAddress从JNI访问它。 This would let you use a Java-side threadpool to manage the work, and would eliminate any native-side concerns about buffer copies. 这将允许您使用Java端线程池来管理工作,并将消除任何关于缓冲区副本的本机方面的担忧。

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

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