使用本机接口的多个java线程与多线程本机的单个java线程相比
Multiple java threads using native interface vs single java thread for multi threaded native
我正在为一个项目做准备,该项目使用JNI来加速物理建模的一些计算。Native part对一组数组进行计算,每个数组都有超过10M个元素。
问题:哪个选项更适合性能:
1) 使用java中的8个线程,每个线程通过本机调用(jni-->c++)处理数组的1/8部分。我是否需要将整个阵列裁剪成更小的阵列,以防止不必要的阵列复制?
2) 在java中使用单线程来调用8线程的本机(pthreads?)我可以使用指针算法只选择线程中需要使用的部分吗?
我需要处理数组的单个副本(或原始副本),c++线程是否为自己复制整个数组?java线程呢?哪一个不是复制的,我会用那个。
注意:我使用GetPrimitiveArrayCritical()
来防止JNI接口的数组复制(在原始接口上工作)。计算需要足够长的时间,可以忽略JNI开销。
GetPrimitiveArrayCritical()
固定java数组,因此GC停止工作,直到本机函数释放它,这会影响其他java线程的访问权限吗?
如果extern "C"
很重要,则实际上所有内容都在其中。
操作系统:64位windows7CPU:fx8150jvm:64位GCC:64位
谢谢。
从设计的角度来看,我更喜欢方法#1,因为这意味着您不必管理JNI代码中的线程。这遵循了"单一责任原则":只有当您的算法发生变化时,您的本地代码才需要更改。我还认为Java提供的工具(线程池和期货)比直接线程更容易使用。
但是,如果您这样做,您应该特别注意关于从多个线程固定和取消固定数组的警告。
IMO的一个更好的方法是分配直接ByteBuffer
,并使用GetDirectBufferAddress从JNI访问它。这将允许您使用Java端线程池来管理工作,并消除任何本机端对缓冲区副本的担忧。
- 如何在JNI中从线程内部调用JAVA方法
- C 多线程JAVA JNI方法调用
- 线程中的异常 "main" java.lang.UnsatisfiedLinkError: no JNTIest in java.library.path
- 通过其他线程通过JNI呼叫保存的Java对象
- 从 Java 线程到 C++
- 线程"main" java.lang.UnsatisfiedLinkError: Native.initiate(I)V 从 Java 运行本机 dll 时
- JNI : 线程"AWT-EventQueue-0" java.lang.UnsatisfiedLinkError 中的异常
- Java:调用本机方法,给出"线程"main"java.lang.UnsatisfiedLinkError中的异常"
- JNI - Java 在本机线程完成执行之前退出
- 通过JNI从本机线程回调时Java线程泄漏
- 与单线程相比,c++/java的多线程性能结果参差不齐
- 线程"main" java.lang.UnsatisfiedLinkError: java.library.path 中没有libopencv_java247
- 在多线程程序中共享资源 C++ 与 Java
- JNI 中的 Java 线程C++仅使用一个内核的环境.Arm 处理器和 Ubuntu
- 在 Python 和 Java 中设置线程亲和力
- Java 中的线程与 C++ 中的线程不同吗?
- Java 和 C++/Qt 中的线程差异
- JNI使用多个线程从C++调用Java
- C++创建线程池(类似于java)
- 线程"main" java.lang.UnsatisfiedLinkError 中的异常