JNI vs JNA rendimiento


Tenemos una aplicación nativa c/asm que utiliza GPU(OpenCL) para un gran encrypt/decrypt datos con un método específico, y simplemente funciona perfecto, no hay problema. Una parte del proyecto (web y distribución) está siendo desarrollada por JEE, y solo necesitamos llamar a la aplicación/biblioteca nativa.

Hemos intentado llamarlo como un proceso externo separado usando la clase Process. El problema es que no podemos controlar la aplicación (evento, manejadores, subprocesos, etc.)...). También tratamos de cambiar el código C en Código Java, pero el rendimiento murió. Excepto ejecutar el código nativo como proceso, estoy pensando en JNA y JNI, pero hay algunas preguntas.

Preguntas:

  1. Para una mejor solución de lectura/escritura(más rápida), ¿es posible intercambiar datos por memoria directa(no administrada) [Java(ByteBuffer#allocateDirect())] tanto en JNI como en JNA?
  2. ¿Es posible administrar y manejar el proceso por código nativo, y acceder a la memoria GPU(compartida) a través de código Java(OpenCL lib)?
  3. ¿Qué pasa con ¿actuación? ¿El JNA es más rápido que el JNI?

Tenemos dos dispositivos agrupados AMD W7000 en Redhat Linux6 x64.

Author: juan.facorro, 2014-03-10

4 answers

El JNA es mucho más lento que el JNI, pero mucho más fácil. Si el rendimiento no es un problema, utilice JNA.

El uso de buffers directos tiene la ventaja de que las operaciones más críticas no utilizan JNI o JNA y, por lo tanto, son más rápidas. Usan intrínseco cuando significa que se convierten en instrucciones de código de máquina individual.

Si el código Java es significativamente más lento que C, es probable que el código no se haya optimizado lo suficiente. En general, la GPU debe estar haciendo todo el trabajo, por lo que si Java es un poco más lento, esto no debería hacer mucha diferencia.

Por ejemplo, si pasas el 99% del tiempo en la GPU y Java tarda el doble, el total será 99+2% o 1% más lento.

 34
Author: Peter Lawrey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-09 22:54:53

El crunching de números pesados se realiza en C/GPU, todo lo que su interfaz Java > C hace es barajar los datos de entrada/salida. Me sorprendería que esto sea un cuello de botella.

En cualquier caso, escriba el código más simple y claro que haga el trabajo. Si resulta que el rendimiento no es suficiente, mida dónde están los cuellos de botella y enfréntelos uno por uno hasta que el rendimiento esté bien. El tiempo del programador es mucho más valioso que el tiempo de la computadora, excepto por circunstancias muy especiales.

 8
Author: vonbrand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-09 22:57:08

De Las preguntas frecuentes oficiales de JNA :

¿Cómo se compara el rendimiento del JNA con el JNI personalizado?

La asignación directa de JNA puede proporcionar un rendimiento cercano al de JNI personalizado. Casi todas las funciones de asignación de tipos de la asignación de interfaces están disponibles, aunque la conversión automática de tipos probablemente incurra en cierta sobrecarga.

La sobrecarga de llamadas para una sola llamada nativa utilizando la asignación de interfaz JNA puede ser un orden de magnitud (~10X) mayor que el tiempo equivalente de JNI personalizado (si realmente lo hace en el contexto de su solicitud es una pregunta diferente). En términos brutos, la sobrecarga de llamadas es del orden de cientos de microsegundos en lugar de decenas de microsegundos. Tenga en cuenta que esa es la sobrecarga de llamadas, no el tiempo total de llamada. Esta magnitud es típica de la diferencia entre los sistemas que utilizan información de tipo mantenida dinámicamente y los sistemas donde la información de tipo se compila estáticamente. JNI hard-codes escriba información en la invocación del método, donde JNA la asignación de interfaz determina dinámicamente la información de tipo en tiempo de ejecución.

Se puede esperar un aumento de velocidad de aproximadamente un orden de magnitud que se mueve a la asignación directa de JNA, y un factor de dos o tres que se mueve desde allí a JNI personalizado. La diferencia real variará dependiendo del uso y las firmas de función. Al igual que con cualquier proceso de optimización, primero debe determinar dónde necesita un aumento de velocidad y luego ver cuánta diferencia hay realizando optimizaciones específicas. La facilidad de la programación de todo en Java generalmente supera las pequeñas ganancias de rendimiento cuando se usa JNI personalizado.

 8
Author: Benoit Blanchon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-10 10:08:23

Desarrollé un dll simple y puse una función vacía que no hace nada. Luego llamé a esa función desde dll con JNA y también JNI, así que traté de calcular el costo de llamarlos. Cuando se busca el rendimiento después de muchas llamadas, JNI era 30-40 veces más rápido que JNA.

 7
Author: Mustafa Kemal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-07 05:57:18