Я хотел бы расширить ответ, предоставленный @Jason S. Используя метод подразделения домена, аналогичный описанному @Jason S, и используя приближения серии Маклорена, среднее (2-3) X ускорение по сравнению с tan (), sin () , cos (), atan (), asin () и acos (), встроенные в компилятор gcc, с оптимизацией -O3. Лучшие аппроксимирующие функции ряда Маклорена, описанные ниже, достигли точности двойной точности.
Для функций tan (), sin () и cos () и для простоты перекрывающаяся область от 0 до 2pi + pi / 80 была разделена на 81 равный интервал с «точками привязки» в pi / 80, 3pi / 80, ..., 161 дюйм / 80. Тогда тангенс (), SIN () и COS () эти 81 опорных точек были оценены и сохранен. С помощью триггерных идентификаторов для каждой триггерной функции была разработана одна функция серии Маклорена. Любой угол между ± бесконечностью может быть представлен триггерной аппроксимирующей функции, поскольку функции сначала переводят входной угол в область от 0 до 2pi. Эти накладные расходы на перевод включены в накладные расходы аппроксимации.
Аналогичные методы были разработаны для функций atan (), asin () и acos (), где перекрывающийся домен от -1,0 до 1,1 был разделен на 21 равный интервал с точками привязки в -19/20, -17/20, .. ., 19/20, 21/20. Тогда только atan () из этих 21 точек привязки был сохранен. Опять же, с помощью тождеств обратных триггеров, для функции atan () была разработана одна функция ряда Маклорена. Затем результаты функции atan () использовались для аппроксимации asin () и acos ().
Поскольку все аппроксимирующие функции обратного триггера основаны на аппроксимирующей функции atan (), разрешено любое входное значение аргумента двойной точности. Однако аргумент, входящий в аппроксимирующие функции asin () и acos (), усекается до области ± 1, потому что любое значение вне его не имеет смысла.
Чтобы проверить аппроксимирующие функции, необходимо было оценить миллиард случайных оценок функций (то есть оптимизирующему компилятору -O3 не разрешалось обходить оценку чего-либо, потому что некоторые вычисленные результаты не использовались). Чтобы удалить смещение оценки миллиарда случайных чисел и обработки результатов, сначала рассчитывалась стоимость запуска без оценки какой-либо триггерной или обратной триггерной функции. Затем это смещение вычиталось из каждого теста, чтобы получить более репрезентативное приближение фактического времени оценки функции.
Таблица 2. Время, затраченное в секундах на выполнение указанной функции или функций миллиард раз. Оценки получаются путем вычитания временных затрат на оценку одного миллиарда случайных чисел, показанных в первой строке таблицы 1, из остальных строк таблицы 1.
Время, проведенное в загар (): 18.0515 18.2545
Время нахождения в TAN3 (): 5.93853 6.02349
Время, проведенное в TAN4 (): 6.72216 6.99134
Время, проведенное в sin () и cos (): 19,4052 19,4311
Время, проведенное в SINCOS3 (): 7.85564 7.92844
Время, проведенное в SINCOS4 (): 9,36672 9,57946
Время нахождения в атане (): 15.7160 15.6599
Время нахождения в ATAN1 (): 6.47800 6.55230
Время, проведенное в ATAN2 (): 7.26730 7.24885
Время нахождения в ATAN3 (): 8.15299 8.21284
Время, проведенное в asin () и acos (): 36,8833 36,9496
Время, проведенное в ASINCOS1 (): 10,1655 9,78479
Время, проведенное в ASINCOS2 (): 10,6236 10,6000
Время, проведенное в ASINCOS3 (): 12.8430 12.0707
(В целях экономии места таблица 1 не показана.) Таблица 2 показывает результаты двух отдельных прогонов миллиарда оценок каждой аппроксимирующей функции. Первый столбец - это первый прогон, а второй столбец - второй прогон. Цифры «1», «2», «3» или «4» в именах функций указывают количество терминов, используемых в функции ряда Маклорена для оценки конкретного триггерного или обратного триггерного приближения. SINCOS # () означает, что sin и cos были вычислены одновременно. Аналогичным образом, ASINCOS # () означает, что asin и acos оценивались одновременно. Одновременная оценка обеих величин не требует дополнительных затрат.
Результаты показывают, что увеличение количества условий немного увеличивает время выполнения, как и следовало ожидать. Даже наименьшее количество членов дает точность около 12-14 цифр везде, за исключением приближения tan (), где его значение приближается к ± бесконечности. Можно было бы ожидать, что даже у функции tan () будут проблемы.
Аналогичные результаты были получены на ноутбуке MacBook Pro высокого класса в Unix и на настольном компьютере высокого класса в Linux.