在Java中使用“sincos”
在很多情况下,我不仅需要正弦,还需要相同参数的余弦。
对于C,在常见的unix数学库中有一个函数。实际上,至少在i386上,这应该是一个单一的汇编指令。sincos
m
fsincos
sincos, sincosf, sincosl - 同时计算 sin 和 cos
我想这些好处之所以存在,是因为计算正弦和余弦有明显的重叠:。但是 AFAIK 尝试将其快捷方式作为 是没有回报的,因为该函数的成本相似。sin(x)^2 + cos(x)^2 = 1
cos = Math.sqrt(1 - sin*sin)
sqrt
有没有办法在Java中获得同样的好处?我想我会为此付出代价;这可能会使所有的努力变得毫无意义,因为增加了垃圾收集。double[]
或者 Hotspot 编译器是否足够聪明,能够认识到我需要两者,并将它编译为命令?我是否可以测试它是否识别它,我能否帮助它识别这一点,例如,通过确保和命令在我的代码中直接连续?从Java语言的角度来看,这实际上是最有意义的:让comiler优化它以使用汇编调用。sincos
Math.sin
Math.cos
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
应该需要一个额外的流行音乐,但这应该在1个时钟周期。假设CPU也没有优化这一点,应该几乎是调用两次的两倍(第二次计算余弦;所以我认为它需要做一个加法)。 在某些情况下可能会更快,但正弦可以更快。sincos
sin
sqrt
更新:我在C中做了一些实验,但它们没有定论。有趣的是,它似乎比(没有)稍微快一点,并且GCC编译器将在您计算两者时使用- 所以它做了我希望Hotspot做的事情(或者Hotspot也是如此?)。我还无法阻止编译器通过使用来战胜我,除非不使用.然后它将回退到 C ,而不是 。sincos
sin
cos
fsincos
sin
cos
fsincos
cos
sin
fsin