JNI与JNA表现

时间:2014-03-09 22:14:35

标签: java c concurrency java-native-interface jna

我们有一个使用GPU(OpenCL)的本地c/asm应用程序,用于具有特定方法的大encrypt/decrypt数据,它只是完美的,没问题。项目的一部分(Web和分发)由JEE开发,我们只需要调用本机应用程序/库。

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

问题:

  1. 为了更好(更快)的读/写解决方案,是否可以通过JNI和JNA中的直接(非托管)内存[Java(ByteBuffer#allocateDirect())]交换数据?
  2. 是否可以通过本机代码管理和处理进程,并通过Java代码(OpenCL lib)访问GPU(共享)内存?
  3. 表现怎么样? JNA比JNI快吗?
  4. 我们在Redhat Linux6 x64上有两台AMD W7000集群设备。

4 个答案:

答案 0 :(得分:34)

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

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

如果Java代码明显慢于C,那么代码可能还没有得到足够的优化。通常GPU应该完成所有工作,所以如果Java有点慢,这应该没什么区别。

e.g。如果你花费99%的时间在GPU上,而Java需要两倍的时间,那么总数将增加99 + 2%或1%。

答案 1 :(得分:9)

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

答案 2 :(得分:9)

来自JNA's official FAQ

  

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

     

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

     

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

     

你可能会期望大约一个数量级的加速转移到JNA直接映射,并且从那里移动到自定义JNI的因子是两个或三个。实际差异将根据使用情况和功能签名而有所不同。与任何优化过程一样,您应首先确定需要提高速度的位置,然后通过执行有针对性的优化来确定存在多大差异。使用自定义JNI时,使用Java编程所有内容的简便性通常会超过小的性能提升。

答案 3 :(得分:8)

重数字运算在C / GPU中完成,所有Java< - > C接口确实是shuffle数据输入/输出。如果这是一个瓶颈,我会感到很惊讶。

在任何情况下,编写完成工作的最简单,最清晰的代码。如果结果表明性能不够,测量瓶颈所在的位置,并逐一解决它们,直到性能良好。除非常特殊的情况,程序员时间比计算机时间更有价值。