That is really interesting re: the recent threads about the value of log() and pow() in the JVM. I think it's worth copying to dev@ here.
---------- Forwarded message --------- From: Tianhua huang <huangtianhua...@gmail.com> Date: Mon, Jul 29, 2019 at 5:28 AM Subject: Fwd: The result of Math.log(3.0) is different on x86_64 and aarch64? To: Sean Owen <sro...@gmail.com> Sorry to disturb you, I forward the jdk-dev email to you, maybe you are interesting :) ---------- Forwarded message --------- From: Pengfei Li (Arm Technology China) <pengfei...@arm.com> Date: Mon, Jul 29, 2019 at 5:52 PM Subject: RE: The result of Math.log(3.0) is different on x86_64 and aarch64? To: bo zhaobo <bzhaojyathousa...@gmail.com>, Tianhua huang <huangtianhua...@gmail.com>, Deshpande, Vivek R <vivek.r.deshpa...@intel.com> Cc: jdk-...@openjdk.java.net <jdk-...@openjdk.java.net>, aarch64-port-...@openjdk.java.net <aarch64-port-...@openjdk.java.net>, nd <n...@arm.com> Hi Bo, Tianhua, Thanks for reporting this issue. You could CC aarch64-port-...@openjdk.java.net if you find something strange on AArch64 server next time. > >> Sorry to disturb you again, I took some tests of java.lang.Math.log > >> function on aarch64 server, I met a strange case, the result of > >> Math.log(3.0) is different with x86_64: > >> on x86_64: > >> scala> Math.log(3.0) res50: Double = 1.0986122886681098 > >> > >> but on aarch64: > >> scala> Math.log(3.0) res19: Double = 1.0986122886681096 I've reproduced this on both JDK12 and latest JDK master (14) with below Java code. public class Test { public static void main(String[] args) { double d = Math.log(3.0); String hex = Long.toHexString(Double.doubleToRawLongBits(d)); System.out.println(d + "(0x" + hex + ")"); } } (x86_64)~$ java Test 1.0986122886681098(0x3ff193ea7aad030b) (aarch64)~$ java Test 1.0986122886681096(0x3ff193ea7aad030a) >From above results we see the least significant bit differs on aarch64 from that on x86_64. So which one is more accurate? By exploring HotSpot code, we could see a method "__ieee754_log(double x)"[1] in shared (architecture independent) code which computes the log(double). But this SharedRuntime method is called only if the architecture specific "StubRoutine::dlog()" is NULL. See [2] for this logic in the C2 compiler but there is no big difference in C1 or the interpreter. I.e. The Math.log(3.0) actually calls into some hand-crafted assembly code if it's generated. By looking into the cpu-specific stuff, we could found that the log() routine is generated on x86_64[3], but disable on aarch64[4] due to issues found before. In another word, the Math.log() call is optimized by HotSpot intrinsics located at [5] on x86_64 but just uses __ieee_754_log() on aarch64. To prove what I've seen is right, I tested my above Java code with VM options "-XX:+UnlockDiagnosticVMOptions -XX:-InlineMathNatives" on both x86_64 and aarch64. (x86_64)~$ java -XX:+UnlockDiagnosticVMOptions -XX:-InlineMathNatives Test 1.0986122886681096(0x3ff193ea7aad030a) (x86_64)~$ java Test 1.0986122886681098(0x3ff193ea7aad030b) DIFFERENT! (aarch64)~$ java -XX:+UnlockDiagnosticVMOptions -XX:-InlineMathNatives Test 1.0986122886681096(0x3ff193ea7aad030a) (aarch64)~$ java Test 1.0986122886681096(0x3ff193ea7aad030a) SAME! >From the results we see that, if we have the assumption shared method __ieee754_log(double) is correct, there should be nothing wrong in aarch64 HotSpot. Instead, the x86_64 log intrinsics may have done some optimization that destroys the accuracy. We need an Intel engineer (maybe ~vdeshpande) to look at the code. [1] http://hg.openjdk.java.net/jdk/jdk/file/2116221e2dde/src/hotspot/share/runtime/sharedRuntimeTrans.cpp#l113 [2] http://hg.openjdk.java.net/jdk/jdk/file/2116221e2dde/src/hotspot/share/opto/library_call.cpp#l1870 [3] http://hg.openjdk.java.net/jdk/jdk/file/2116221e2dde/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp#l5906 [4] http://hg.openjdk.java.net/jdk/jdk/file/2116221e2dde/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp#l5700 [5] http://hg.openjdk.java.net/jdk/jdk/file/2116221e2dde/src/hotspot/cpu/x86/macroAssembler_x86_log.cpp#l185 -- Thanks, Pengfei --------------------------------------------------------------------- To unsubscribe e-mail: dev-unsubscr...@spark.apache.org