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]
