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

使用本机接口的多个java线程与使用多线程本机接口的单个java线程,java,c++,c,java-native-interface,Java,C++,C,Java Native Interface,我正在准备一个项目,使用JNI来加速物理建模的一些计算。Native part对一组数组进行计算,每个数组的元素数超过10M 问题:哪种选择更适合绩效: 1在java中使用8个线程,每个线程通过本机calljni->c++处理数组的1/8部分。是否需要将整个阵列裁剪为更小的阵列,以防止不必要的阵列复制 2在java中使用单线程调用本机线程,即8线程pthreads? 我可以使用指针算法只选择线程中需要使用的部分吗 我需要处理一个数组的原始拷贝,C++线程是否复制了整个数组?java线程呢?哪一个

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

问题:哪种选择更适合绩效:

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

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

我需要处理一个数组的原始拷贝,C++线程是否复制了整个数组?java线程呢?哪一个不是复制的,我会用那个

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

GetPrimitiveArrayCritical固定java数组,以便GC在本机函数释放它之前停止工作,这是否会影响其他java线程的可访问性

实际上,如果重要的话,所有的都在一个外部C中

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


谢谢。

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

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


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

谢谢,警告中提到的gcc标志很好。我也会等待一些其他的答案,否则我会除了你的答案。你的意思是我应该将数组裁剪成8个部分,然后将它们提供给使用本机函数的独立线程。这样,他们就不能用未完成的工作取消绑定数组。@huseyintugrulbuyukisik-不,我认为最好的方法是保留一个缓冲区,并将该缓冲区中的地址范围传递给工作者。根本不使用原始数组。我在java中没有使用任何直接缓冲区。如果你不介意的话,你能举个例子吗?实际上用于jmonkey引擎,但那一定不同,对吗?我使用了FloatBuffer。directbytebuffer是否被固定/取消固定?@huseyintugrulbuyukisik-直接缓冲区位于C堆上,因此不需要固定/取消固定,或者更准确地说,它总是固定的。一旦您从我链接的方法中获得它的地址,您就可以像使用C数组一样使用它。