在很多情况下,我不仅需要正弦,还要求相同参数的余弦.
对于C,常见的unix m数学库中存在sincos函数.实际上,至少在i386上,这应该是一个单一的汇编指令fsincos.
sincos, sincosf, sincosl – calculate sin and cos simultaneously
我猜这些好处是存在的,因为计算正弦和余弦有一个明显的重叠:sin(x)^ 2 cos(x)^ 2 = 1但是,AFAIK它没有回报,试图将其作为cos = Math.sqrt (1-sin * sin),因为sqrt函数的成本相似.
有没有办法在Java中获得同样的好处?我想我现在要支付双倍的价格[]这可能会使所有的努力都因为添加的垃圾收集而产生.
或者,Hotspot编译器很聪明,足以认识到我需要两者,并将它编译成一个sincos命令?我可以测试它是否识别它,我可以帮助它识别,例如通过确保Math.sin和Math.cos命令在我的代码中是直接连续的?从Java语言的角度来看,这实际上是最有意义的:让comiler优化它以使用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做了一些实验,但他们没有结果.有趣的是,sincos似乎比sin(没有cos)要快一些,GCC编译器会在计算sin和cos时使用fsincos,所以它可以做我想要的Hotspot(或者Hotspot)呢? ).我不能阻止编译器通过使用fsincos来超越我,除非不使用cos.然后它会回到一个C罪,不是fsin.