jblas-project / jblas

Linear Algebra for Java
http://jblas.org
BSD 3-Clause "New" or "Revised" License
590 stars 149 forks source link

Must use GetPrimitiveArrayCritical instead of Get<type>ArrayElements for better performance #129

Open javaNoviceProgrammer opened 3 years ago

javaNoviceProgrammer commented 3 years ago

https://github.com/jblas-project/jblas/blob/acf3407be6b0a978a36a1c744e9f3fec4808d36a/src/main/c/NativeBlas.c#L255

It's always best to use critical access to primitive arrays using JNI ("GetPrimitiveArrayCritical") instead of using "GetArrayElements". The latter always makes a copy of the original array behind the scenes which is very bad for performance.

Here's my lecture on critical access using JNI: https://www.youtube.com/watch?v=PIaGaUeHlXU&list=PLWchVAowvRxCcofHJM62gI-CcRD14Apg9&index=4 Here are my full lectures: https://www.youtube.com/playlist?list=PLWchVAowvRxCc4N5F5RTJnDV150Vf7ouf Here's my science4j workspace: https://github.com/javaNoviceProgrammer/science4j

mikiobraun commented 3 years ago

Hi, thanks for pointing this out.

I'm aware of the copying (e.g. discussed here http://blog.mikiobraun.de/2008/10/matrices-jni-directbuffers-and-number.html), but thankfully, many matrix operations are slower than O(n), so the copying is negligible. In fact, this is one of the reasons why I do not call the native BLAS methods for low-level O(n) operations like addition.

When have the critical methods been introduced? Either I completely missed them or they have been added after 2008?

Happy to revisit, however, so again thanks for the pointer!

Looking for more documentation, I found this: https://stackoverflow.com/questions/23258357/whats-the-trade-off-between-using-getprimitivearraycritical-and-getprimitivety which mentions some potential issues if the call takes very long. As matrix multiplications can in fact take quite long (minutes), do you have any experience how that would affect the code?