Java JNI 与 JNA 性能

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22288909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 14:45:54  来源:igfitidea点击:

JNI vs. JNA performance

javacconcurrencyjava-native-interfacejna

提问by

We have a native c/asmapplication utilizing GPU(OpenCL) for a big encrypt/decryptdata with a specific method, and it just works perfect, no problem. A part of the project (web and distribution) is been developing by JEE, and we just need to call native application/library.

我们有一个c/asm使用 GPU(OpenCL)以encrypt/decrypt特定方法处理大数据的本机应用程序,它运行完美,没问题。项目的一部分(网络和发行版)正在由 开发JEE,我们只需要调用原生应用程序/库。

We have tried to call it as a separated-external process using Processclass. The problem is that we cannot control the application(event, handlers, threads, etc...). We also tried to just switch the C code into Java code, but the performance died. Except running the native code as process, I'm thinking about JNA and JNI, but there are some questions.

我们尝试将其称为使用Process类的分离的外部进程。问题是我们无法控制应用程序(事件、处理程序、线程等...)。我们还尝试将 C 代码转换为 Java 代码,但性能下降。除了将本机代码作为进程运行之外,我正在考虑 JNA 和 JNI,但还有一些问题。

Questions:

问题:

  1. For better(faster) read/write solution, is it possible to exchange data by direct(unmanaged) memory [Java(ByteBuffer#allocateDirect())] in both JNI and JNA?
  2. Is it possible to manage and handle process by native code, and access the GPU(shared) memory through Java code(OpenCL lib)?
  3. What about performance? Is JNA faster than JNI?
  1. 为了更好(更快)的读/写解决方案,是否可以通过ByteBuffer#allocateDirect()JNI 和 JNA 中的直接(非托管)内存 [Java( )]交换数据?
  2. 是否可以通过本机代码管理和处理进程,并通过 Java 代码(OpenCL lib)访问 GPU(共享)内存?
  3. 性能呢?JNA 比 JNI 快吗?

We have two AMD W7000 clustered device on Redhat Linux6 x64.

我们在 Redhat Linux6 x64 上有两个 AMD W7000 集群设备。

采纳答案by Peter Lawrey

JNA is much slower than JNI, but much easier. If performance is not an issue use JNA.

JNA 比 JNI 慢得多,但容易得多。如果性能不是问题,请使用 JNA。

Using direct buffers have the advantage that the most critical operations don't use JNI or JNA and are thus faster. They use intrinsic when means they get turned into single machine code instructions.

使用直接缓冲区的优点是最关键的操作不使用 JNI 或 JNA,因此速度更快。当它们变成单个机器代码指令时,它们使用内在方法。

If Java code is significantly slower than C it is likely the code hasn't been optimised enough. Generally the GPU should be doing all the work so if Java is a bit slower this shouldn't make much difference.

如果 Java 代码明显比 C 慢,则可能是代码没有得到足够的优化。一般来说,GPU 应该做所有的工作,所以如果 Java 有点慢,这应该没有太大区别。

e.g. if you spend 99% of the time in the GPU and Java takes twice as long the total will be 99+2% or 1% slower.

例如,如果您将 99% 的时间花在 GPU 上,而 Java 花费的时间是原来的两倍,那么总时间将慢 99+2% 或 1%。

回答by vonbrand

The heavy number crunching is done in C/GPU, all your Java <--> C interface does is shuffle data in/out. I'd be suprised if this is a bottleneck.

繁重的数字运算是在 C/GPU 中完成的,您的 Java <--> C 接口所做的只是将数据输入/输出。如果这是一个瓶颈,我会感到惊讶。

In any case, write the simplest, clearest code that does the job. If it turns out performance isn't enough, measurewhere the bottlenecks are, and tackle them one by one until performance is OK. Programmer time is much more valuable than computer time, except for very special circumstances.

无论如何,编写最简单、最清晰的代码来完成这项工作。如果结果证明性能不够,则测量瓶颈所在,并一一解决它们,直到性能正常为止。除了非常特殊的情况外,程序员的时间比计算机的时间宝贵得多。

回答by Mustafa Kemal

I developed a simple dll and put an empty function which does nothing. Then I called that function from dll with JNA and also JNI, so I tried to calculate cost of calling them. When looking performance after many calls, JNI was 30-40 times faster than JNA.

我开发了一个简单的 dll 并放置了一个什么都不做的空函数。然后我用 JNA 和 JNI 从 dll 调用该函数,所以我试图计算调用它们的成本。在多次调用后查看性能时,JNI 比 JNA 快 30-40 倍。

回答by Benoit Blanchon

From JNA's official FAQ:

来自JNA 的官方常见问题解答

How does JNA performance compare to custom JNI?

JNA direct mapping can provide performance near that of custom JNI. Nearly all the type mapping features of interface mapping are available, although automatic type conversion will likely incur some overhead.

The calling overhead for a single native call using JNA interface mapping can be an order of magnitude (~10X) greater time than equivalent custom JNI (whether it actually does in the context of your application is a different question). In raw terms, the calling overhead is on the order of hundreds of microseconds instead of tens of microseconds. Note that that's the call overhead, not the total call time. This magnitude is typical of the difference between systems using dynamically-maintained type information and systems where type information is statically compiled. JNI hard-codes type information in the method invocation, where JNA interface mapping dynamically determines type information at runtime.

You might expect a speedup of about an order of magnitude moving to JNA direct mapping, and a factor of two or three moving from there to custom JNI. The actual difference will vary depending on usage and function signatures. As with any optimization process, you should determine first where you need a speed increase, and then see how much difference there is by performing targeted optimizations. The ease of programming everything in Java usually outweighs small performance gains when using custom JNI.

JNA 性能与自定义 JNI 相比如何?

JNA 直接映射可以提供接近于自定义 JNI 的性能。几乎所有接口映射的类型映射功能都可用,尽管自动类型转换可能会产生一些开销。

使用 JNA 接口映射的单个本机调用的调用开销可能比等效的自定义 JNI 时间长一个数量级(约 10 倍)(它是否确实在您的应用程序上下文中执行是一个不同的问题)。在原始术语中,调用开销大​​约为数百微秒而不是数十微秒。请注意,这是呼叫开销,而不是总呼叫时间。这种量级是使用动态维护类型信息的系统与静态编译类型信息的系统之间的典型差异。JNI 在方法调用中硬编码类型信息,其中 JNA 接口映射在运行时动态确定类型信息。

您可能期望转为 JNA 直接映射的速度提高大约一个数量级,而从那里转为自定义 JNI 的速度为 2 或 3 倍。实际差异将根据用法和函数签名而有所不同。与任何优化过程一样,您应该首先确定需要提高速度的位置,然后通过执行有针对性的优化来查看差异有多大。在使用自定义 JNI 时,用 Java 编写所有内容的简便性通常会超过小的性能提升。