Во многих ситуациях мне нужен не только синус, но и косинус того же параметра.
Для C существует функция sincos
в общей библиотеке unix m
. И на самом деле, по крайней мере на i386, это должна быть одна инструкция сборки, fsincos
.
sincos, sincosf, sincosl - вычислять sin и cos одновременно
Я предполагаю, что эти преимущества существуют, потому что есть очевидное совпадение в вычислении синуса и косинуса: sin(x)^2 + cos(x)^2 = 1
. Но AFAIK не рассчитывает сократить это как cos = Math.sqrt(1 - sin*sin)
, так как функция sqrt
поставляется с аналогичной стоимостью.
Есть ли способ получить те же преимущества в 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
должен нуждаться в дополнительной поп-музыке, но это должно быть на 1 такт. Предполагая, что CPU также не оптимизирует это, sincos
должен быть почти в два раза быстрее, чем вызов sin
дважды (второй раз для вычисления косинуса, поэтому я считаю, что ему нужно будет добавить дополнение). sqrt
может быть быстрее в некоторых ситуациях, но синус может быть быстрее.
Обновление. Я провел несколько экспериментов на C, но они неубедительны. Интересно, что sincos
кажется еще немного быстрее, чем sin
(без cos
), и компилятор GCC будет использовать fsincos
при вычислении как sin
, так и cos
- поэтому он делает то, d нравится Hotspot делать (или тоже Hotspot?). Я еще не мог помешать компилятору перехитрить меня, используя fsincos
, но не используя cos
. Затем он вернется к C sin
, а не к fsin
.