多くの場合、同じパラメータの正弦だけでなく余弦も必要です。
C の場合sincos
、共通の UNIXm
数学ライブラリに関数があります。実際、少なくとも i386 では、これは単一のアセンブリ命令である必要がありますfsincos
。
sincos, sincosf, sincosl - sin と cos を同時に計算する
正弦と余弦の計算には明らかな重複があるため、これらの利点が存在すると思いますsin(x)^2 + cos(x)^2 = 1
。cos = Math.sqrt(1 - sin*sin)
しかし、sqrt
関数には同様のコストがかかるため、これを as としてショートカットしようとしても報われません。
Javaで同じ利点を享受する方法はありますか? その代償を払うことになると思いdouble[]
ます。ガベージコレクションが追加されているため、すべての努力が無駄になる可能性があります。
または、Hotspot コンパイラは、両方が必要であることを認識し、これをsincos
コマンドにコンパイルするほどスマートですか? Math.sin
それが認識されているかどうかをテストできますか? また、コード内でコマンドとMath.cos
コマンドが直接連続していることを確認するなどして、これを認識できるようにすることはできますか? これは実際には、Java 言語の観点から最も理にかなっています。つまり、fsincos
アセンブリ呼び出しを使用するようにコミラーにこれを最適化させることです。
いくつかのアセンブラーのドキュメントから収集:
Variations 8087 287 387 486 Pentium
fsin - - 122-771 257-354 16-126 NP
fsincos - - 194-809 292-365 17-137 NP
Additional cycles required if operand > pi/4 (~3.141/4 = ~.785)
sqrt 180-186 180-186 122-129 83-87 70 NP
fsincos
余分な pop が必要ですが、それは 1 クロック サイクルで発生するはずです。CPUもこれを最適化しないと仮定すると、 2回sincos
呼び出すよりもほぼ2倍高速になるはずですsin
(コサインを計算するのは2回目です。したがって、加算を行う必要があると思います)。sqrt
状況によっては、sine の方が速い場合もありますが、sine の方が速い場合があります。
更新: C でいくつかの実験を行いましたが、決定的ではありません。興味深いことに、 (なし)sincos
よりもわずかに高速であるように思われ、両方を計算するときにGCC コンパイラーが使用するので、Hotspot に実行してもらいたいことを実行します (または、Hotspot も実行しますか?)。を使用せずに except を使用することで、コンパイラが私を裏切ることをまだ防ぐことはできませんでした。その後、 ではなくC にフォールバックします。sin
cos
fsincos
sin
cos
fsincos
cos
sin
fsin