我正在准备一个使用JNI加速物理建模计算的项目。Native部分在一组数组上执行计算,每个数组都有超过10M个元素。
问题:哪个选项更适合性能:
1)在java中使用8个线程,每个线程通过本机调用(jni-->c++)处理数组的1/8部分。我需要将整个数组裁剪成更小的数组以防止不必要的数组复制吗?
2)在java中使用单线程调用8线程的本机(pthreads?)
我可以使用指针算法来选择线程中所需的部分吗?
我需要处理数组的单个副本(或原始副本),一个c++线程是否为自己复制整个数组?java线程呢?哪一个不是复制品,我用那个。
注意:Im使用GetPrimitiveArrayCritical()来防止JNI接口的数组复制(处理原始的)。
计算需要足够长的时间才能忽略JNI开销。
GetPrimitiveArrayCritical()锁定java数组,以便GC在本机函数释放它之前停止工作,这是否会影响其他java线程的可访问性?
实际上,如果重要的话,所有的都在aextern "C"中。
操作系统:64位windows7
CPU:fx8150
jvm:64位
GCC:64位
谢谢。

最佳答案

从设计的角度来看,我更喜欢方法1,因为它意味着您不必在JNI代码中管理线程。这遵循了“单一责任原则”:如果算法发生更改,则只需更改本机代码。我还认为Java提供的工具(线程池和未来)比直接线程更易于使用。
但是,如果执行此操作,则应特别注意有关从多个线程固定和取消固定数组的warning
IMO更好的方法是分配一个directByteBuffer,并使用GetDirectBufferAddress从JNI访问它。这将允许您使用Java端线程池来管理工作,并消除对缓冲区副本的任何本机端问题。

关于java - 使用 native 接口(interface)的多个Java线程与用于多线程 native 的单个Java线程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17677476/

10-14 17:25
查看更多