Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

jvm - Why does Math.sin() delegate to StrictMath.sin()?

I was wondering, why does Math.sin(double) delegate to StrictMath.sin(double) when I've found the problem in a Reddit thread. The mentioned code fragment looks like this (JDK 7u25):

Math.java :

public static double sin(double a) {
    return StrictMath.sin(a); // default impl. delegates to StrictMath
}

StrictMath.java :

public static native double sin(double a);

The second declaration is native which is reasonable for me. The doc of Math states that:

Code generators are encouraged to use platform-specific native libraries or microprocessor instructions, where available (...)

And the question is: isn't the native library that implements StrictMath platform-specific enough? What more can a JIT know about the platform than an installed JRE (please only concentrate on this very case)? In ther words, why isn't Math.sin() native already?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'll try to wrap up the entire discussion in a single post..

Generally, Math delegates to StrictMath. Obviously, the call can be inlined so this is not a performance issue.

StrictMath is a final class with native methods backed by native libraries. One might think, that native means optimal, but this doesn't necessarily has to be the case. Looking through StrictMath javadoc one can read the following:

(...) the definitions of some of the numeric functions in this package require that they produce the same results as certain published algorithms. These algorithms are available from the well-known network library netlib as the package "Freely Distributable Math Library," fdlibm. These algorithms, which are written in the C programming language, are then to be understood as executed with all floating-point operations following the rules of Java floating-point arithmetic.

How I understand this doc is that the native library implementing StrictMath is implemented in terms of fdlibm library, which is multi-platform and known to produce predictable results. Because it's multi-platform, it can't be expected to be an optimal implementation on every platform and I believe that this is the place where a smart JIT can fine-tune the actual performance e.g. by statistical analysis of input ranges and adjusting the algorithms/implementation accordingly.

Digging deeper into the implementation it quickly turns out, that the native library backing up StrictMath actually uses fdlibm:

StrictMath.c source in OpenJDK 7 looks like this:

   #include "fdlibm.h"
   ...
   JNIEXPORT jdouble JNICALL
   Java_java_lang_StrictMath_sin(JNIEnv *env, jclass unused, jdouble d)
   {
       return (jdouble) jsin((double)d);
   }

and the sine function is defined in fdlibm/src/s_sin.c refering in a few places to __kernel_sin function that comes directly from the header fdlibm.h.


While I'm temporarily accepting my own answer, I'd be glad to accept a more competent one when it comes up.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...