JNI与JNA表现

我们有一个原生的c/asm应用程序利用GPU(OpenCL)通过特定的方法获得大的encrypt/decrypt数据,它只是工作完美,没问题。 项目的一部分(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集群设备。

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

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

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

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

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

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

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

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

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

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

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

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