rednaxelafx edited a comment on issue #25279: [SPARK-28519][SQL] Use StrictMath 
log, pow functions for platform independence
URL: https://github.com/apache/spark/pull/25279#issuecomment-519724379
 
 
   Thanks @srowen ! Basically we just want to make sure if we anticipate there 
are performance implications, some due diligence of benchmarking should be 
done. Thanks for adding that information in this PR for future reference!
   
   BTW, folks that are not intimately familiar with the inner workings of the 
HotSpot JVM may find this interesting:
   While both `java.lang.Math` and `java.lang.StrictMath` are partially 
implemented with `native` functions, they're really different under the hood.
   
   In current OpenJDK8u,
   - java.lang.StrictMath: 
     - Java side: 
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/89c8bfe10659/src/share/classes/java/lang/StrictMath.java
     - native side: 
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/89c8bfe10659/src/share/native/java/lang/StrictMath.c
   - java.lang.Math:
     - Java side: 
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/89c8bfe10659/src/share/classes/java/lang/Math.java
   
   Now, taking one specific example of `Math.log()`:
   ```java
       public static double log(double a) {
           return StrictMath.log(a); // default impl. delegates to StrictMath
       }
   ```
   goes to `StrictMath.log()`:
   ```java
       public static native double log(double a);
   ```
   goes to native code:
   ```c
   JNIEXPORT jdouble JNICALL
   Java_java_lang_StrictMath_log(JNIEnv *env, jclass unused, jdouble d)
   {
       return (jdouble) jlog((double)d);
   }
   ```
   and then `jlog` is actually the `log` function from fdlibm via:
   ```c
   src/share/native/java/lang/fdlibm/include/jfdlibm.h:44:#define log     jlog
   ```
   
   So then `Math.log` and `StrictMath.log` should be the exact same thing? Well 
not so fast.
   In the HotSpot JVM, it treats some Java methods as being "special", aka 
"intrinsics", which means it knows exactly what semantics that method needs to 
implement, and choose an alternative internal implementation for it.
   
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/c7a3e57fdf4a/src/share/vm/classfile/vmSymbols.hpp#l681
   ```c++
     do_intrinsic(_dlog,                     java_lang_Math,         log_name,  
 double_double_signature,           F_S)   \
   ```
   `Math.log()` happens to be one of the intrinsified Java methods. It is 
implemented with special assembler snippets in all of:
   1. Interpreter, e.g.: 
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/c7a3e57fdf4a/src/cpu/x86/vm/interpreter_x86_64.cpp#l269
 -> 
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/c7a3e57fdf4a/src/cpu/x86/vm/assembler_x86.cpp#l4147
   2. C1 compiler, e.g.: 
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/c7a3e57fdf4a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp#l2491
   3. C2 compiler, e.g.: 
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/c7a3e57fdf4a/src/cpu/x86/vm/x86_64.ad#l9859
   4. If you happen to use Graal as the JIT compiler, Graal implements it 
intrinsically as well: 
https://github.com/oracle/graal/blob/3aadf1c959b9d91bd4dbe6dc34aefa34b233f77e/compiler/src/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java#L120
 -> 
https://github.com/oracle/graal/blob/22844a8742eecba19a69e1054907ee9b93d58c78/compiler/src/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMathIntrinsicOp.java#L68
 -> 
https://github.com/oracle/graal/blob/3aadf1c959b9d91bd4dbe6dc34aefa34b233f77e/compiler/src/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java#L305
   
   In all cases in (1) to (3) above, the `Math.log()` method call is actually 
implemented by this x86 instruction sequence on x86_64 in HotSpot:
   ```
   fldln2   # load constant loge 2
   fxch     # exchange floating point registers
   fyl2x    # compute y * log_2(x)
   ```
   
   So while `StrictMath.log()` is always implemented by fdlibm in OpenJDK8u, 
`Math.log()` can be intrinsified into different implementations inside the 
OpenJDK HotSpot JVM that use platform-specific assembler, which can result in 
different results cross platform.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to