JNI与JNA性能比较

40
我们有一个使用GPU(OpenCL)进行大型加密/解密数据的本地应用程序,并采用特定方法,它完美地运行,没有问题。该项目的一部分(Web和分发)由JEE开发,我们只需要调用本地应用程序/库。
我们尝试使用Process类将其作为单独的外部进程调用。问题在于,我们无法控制应用程序(事件、处理程序、线程等等)。我们还尝试将C代码切换为Java代码,但性能下降了。除了将原生代码作为进程运行之外,我正在考虑JNA和JNI,但有一些问题。
问题: 1.为了获得更好(更快)的读/写解决方案,在JNI和JNA中是否可能通过直接(非托管)内存[Java(ByteBuffer#allocateDirect())]交换数据? 2.是否可能通过本地代码管理和处理进程,并通过Java代码(OpenCL lib)访问GPU(共享)内存? 3.JNA比JNI更快吗?
我们在Redhat Linux6 x64上拥有两个AMD W7000集群设备。
4个回答

48

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

使用直接缓冲区的优点在于最关键的操作不使用JNI或JNA,因此速度更快。它们使用内部机制,这意味着它们会转换为单个机器代码指令。

如果Java代码比C代码慢得多,那么很可能代码还没有被充分优化。通常情况下,GPU应该完成所有工作,因此如果Java稍微慢一些,这不应该有太大影响。

例如,如果你在GPU中花费99%的时间,而Java需要两倍的时间,则总时间将变为99+2%或1%较慢。


太感谢你了伙计。我们尝试了很多次将C代码转换为Java,但除了GPGPU之外,我们遇到了一些问题,比如利用AVX、AES和MMX扩展。有趣的是,JNA比JNI慢,我们进行了一些简单的测试,结果表明JNA更快。你说得对,我们需要在Java上花更多时间。谢谢你,伙计:D - user2889419
13
JavaCPP与JNA使用起来一样简单,但速度却像原始JNI一样快。 - Samuel Audet

17

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

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

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

使用JNA接口映射进行单个本地调用的调用开销可能比等效的自定义JNI大一个数量级(约为10倍)(不过实际情况取决于应用程序的上下文)。以原始术语来说,调用开销大约是数百微秒而不是数十微秒。请注意,这是调用开销而不是总调用时间。这种数量级通常是使用动态维护的类型信息和静态编译类型信息的系统之间的差异。 JNI在方法调用中硬编码类型信息,而JNA接口映射在运行时动态确定类型信息。

您可能希望将性能提升一个数量级,从JNA直接映射到自定义JNI则可能提升两到三倍。实际差异将根据使用情况和函数签名而异。与任何优化过程一样,您应首先确定需要提速的地方,然后通过执行有针对性的优化来查看差异的大小。在使用自定义JNI时,完全用Java编程的便利性通常超过小的性能增益。


16

我开发了一个简单的dll,并放置了一些不做任何操作的空函数。然后,我使用JNA和JNI从dll中调用该函数,试图计算它们的调用成本。在进行多次调用后查看性能时,JNI比JNA快30-40倍。


12

数字密集型计算主要在C/GPU中完成,所有的Java <--> C接口只是把数据进出来而已。如果这成为瓶颈,我会感到惊讶。

无论如何,请编写最简单,最清晰的代码来完成任务。如果发现性能不足,测量瓶颈所在,并逐个解决它们,直到性能达到要求。程序员的时间比计算机的时间更加宝贵,除非在非常特殊的情况下例外。


1
非常好的观点,亲爱的。我相信更多的开发时间会带来更优化的应用程序。本地应用程序已经被重视了一段时间,我们可以依靠它。我们总是遇到运行时的问题,比如 JVM 等。谢谢你的支持 :) - user2889419

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接