0

我正在准备一个使用 JNI 来加速物理建模计算的项目。本机部分对一组数组进行计算,每个数组都有超过 10M 的元素。

问题: 哪个选项更适合性能:

1)在java中使用8个线程,每个线程通过本机调用(jni-->c++)处理数组的1/8部分。我是否需要将整个数组裁剪成更小的数组以防止不必要的数组复制?

2)在java中使用单线程调用8线程的本机(pthreads?)我可以使用指针算法只选择在线程中使用的必要部分吗?

我需要处理数组的单个副本(或原始),c++ 线程是否会为自己复制整个数组?java线程呢?哪一个不是抄袭的,我会用那个。

注意:我GetPrimitiveArrayCritical()用来防止 JNI 接口的数组复制(在原始上工作)。计算花费的时间足够长,以至于可以忽略 JNI 开销。

GetPrimitiveArrayCritical()固定java数组,所以GC停止工作,直到本机函数释放它,这会影响其他java线程的可访问性吗?

其实一切都在一个extern "C"如果它是重要的

操作系统:64 位 windows7 CPU:fx8150 jvm:64 位 GCC:64 位

谢谢。

4

1 回答 1

2

从设计的角度来看,我更喜欢方法#1,因为这意味着您不必在 JNI 代码中管理线程。这符合“单一责任原则”:您的本机代码仅在您的算法发生变化时才需要更改。我还认为 Java 提供的工具(线程池和期货)比直接线程更容易使用。

但是,如果您这样做,您应该特别注意有关从多个线程固定和取消固定数组的警告。

更好的方法 IMO 是分配一个direct ByteBuffer,并使用GetDirectBufferAddress从 JNI 访问它。这将允许您使用 Java 端线程池来管理工作,并消除对缓冲区副本的任何本机端问题。

于 2013-07-16T14:52:16.673 回答