Java: implémentation fp 32 bits de Math.sqrt()
La méthode standard Math.sqrt()
semble déjà assez rapide en Java, mais elle a l'inconvénient inhérent qu'elle impliquera toujours des opérations 64 bits qui ne font que réduire la vitesse lorsqu'il s'agit de valeurs 32 bits float
. Est-il possible de faire mieux avec une méthode personnalisée qui utilise un float
comme paramètre, effectue des opérations 32 bits uniquement et renvoie un float
en conséquence?
J'ai vu:
Rapide sqrt en Java au détriment de la précision
Et il a fait peu plus que renforcer la notion que les mathématiques.sqrt() est généralement difficile à battre. J'ai aussi vu:
Http://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi
Qui m'a montré un tas de hacks C++/ASM intéressants que je suis tout simplement trop ignorant pour porter directement vers Java. Bien que sqrt14 puisse être intéressant dans le cadre d'un appel JNI . . .
J'ai également regardé Apache Commons FastMath, mais il semble que cette bibliothèque soit par défaut la norme Mathématique.sqrt () donc pas d'aide là-bas. Et puis il y a Yeppp!:
Mais je ne me suis pas encore soucié de cela.
2 answers
Vous n'avez besoin de rien pour accélérer sqrt
pour les valeurs 32 bits. HotSpot JVM le fait automatiquement pour vous.
Le compilateur JIT est assez intelligent pour reconnaître f2d -> Math.sqrt() -> d2f
pattern et le remplacer par une instruction CPU sqrtss
plus rapide au lieu de sqrtsd
. La source.
La référence:
@State(Scope.Benchmark)
public class Sqrt {
double d = Math.random();
float f = (float) d;
@Benchmark
public double sqrtD() {
return Math.sqrt(d);
}
@Benchmark
public float sqrtF() {
return (float) Math.sqrt(f);
}
}
, Et les résultats:
Benchmark Mode Cnt Score Error Units
Sqrt.sqrtD thrpt 5 145501,072 ± 2211,666 ops/ms
Sqrt.sqrtF thrpt 5 223657,110 ± 2268,735 ops/ms
Comme vous semblez le savoir JNI:
Il suffit d'écrire un wrapper minimal pour double sqrt(double)
et float sqrt(float)
à partir de la bibliothèque standard de C math.h
et de comparer les performances.
Astuce: vous ne sentirez pas de différence à moins de faire beaucoup d'enracinement carré, puis l'avantage de performance d'utiliser les instructions SIMD pour faire plusieurs sqrts à la fois dominera très probablement les effets. Vous devrez obtenir un tableau aligné en mémoire des valeurs à virgule flottante de Java, ce qui peut être assez difficile, si vous utilisez Java bibliothèques standard.