Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Оптимизация тригонометрических функций

1.9K
17 мая 2010 года
Rad87
123 / / 14.12.2005
Не давно открыл для себя то, что расчет тригонометрических функций (sin, cos)весьма затратная вещь.
Как можно ускорить работу этих функций без потери точности результирующего значения?
63
17 мая 2010 года
Zorkus
2.6K / / 04.11.2006
Цитата: Rad87
Не давно открыл для себя то, что расчет тригонометрических функций (sin, cos)весьма затратная вещь.
Как можно ускорить работу этих функций без потери точности результирующего значения?


Разложение в ряд до заданного члена. Потеря точности - неизбежный trade-off.

1.9K
17 мая 2010 года
Rad87
123 / / 14.12.2005
я где то читал, что можно считать с использованием SSE. Стоит ли игра свечь и на сколько это геморно?
7
17 мая 2010 года
@pixo $oft
3.4K / / 20.09.2006
Вообще тригонометрия считается на сопроцессоре.В командах SSE ничего для ко-/синусов не нашёл
63
18 мая 2010 года
Zorkus
2.6K / / 04.11.2006
А собственно, зачем ускорять выполнение тригонометрических функций? :)
1.9K
18 мая 2010 года
Rad87
123 / / 14.12.2005
Цитата: Zorkus
А собственно, зачем ускорять выполнение тригонометрических функций? :)


Когда операции вычисления синусов и косинусов занимает 20% времени работы программы.... начинаешь об этом задумываться ;)

252
18 мая 2010 года
koderAlex
1.4K / / 07.09.2005
учитесь работать с сопроцессором . вот команды :
fsin - синус
fcos - косинус
fsincos - вычисление одновременно синуса и косинуса
fptan - тангенс
fpatan - арктангенс
fsqrt - корень квадратный
11K
18 мая 2010 года
Babandr
76 / / 05.05.2008
А в таблицу загнать не вариант? Хотя, по некоторым данным, на современных процессорах это даст от силы пару процентов выигрыша в производительности - сопроцессоры щас зело быстрые.

Ну или использовать общеизвестные факты о том, например, что при малых значениях аргумента синус и тангенс примерно равны аргументу...ну и все такое.
Хотя, конечно, все зависит от решаемой задачи. Если важна точность до 15 знака после запятой, то тут уже думать надо.
307
18 мая 2010 года
Artem_3A
863 / / 11.04.2008
Цитата: Rad87
я где то читал, что можно считать с использованием SSE. Стоит ли игра свечь и на сколько это геморно?



очевидно автор оной статьи имел в виду, что вы должны сами через разложение в ряд Тэйлора реализовать эти функции с использованием команд SSE. в принципе сие не есть уж очень геморно, но игра не стоит свеч, навряд ли прирост производительности будет ощутим, если он вообще конечно будет.

зы: кстати сейчас товарисчи из интела взялись переписывать стандартные сишные математические библиотеки под новые наборы инструкций. кому интересно можете почитать об этом в летней школе интела, адресок к сожалению не помню.:D:(

1.9K
18 мая 2010 года
Rad87
123 / / 14.12.2005
Цитата: Artem_3A
очевидно автор оной статьи имел в виду, что вы должны сами через разложение в ряд Тэйлора реализовать эти функции с использованием команд SSE. в принципе сие не есть уж очень геморно, но игра не стоит свеч, навряд ли прирост производительности будет ощутим, если он вообще конечно будет.

зы: кстати сейчас товарисчи из интела взялись переписывать стандартные сишные математические библиотеки под новые наборы инструкций. кому интересно можете почитать об этом в летней школе интела, адресок к сожалению не помню.:D:(



http://gruntthepeon.free.fr/ssemath/

1.9K
18 мая 2010 года
Rad87
123 / / 14.12.2005
похоже нужно уменьшать частоту вызова тригонометрических функций и оптимизировать сам алгоритм.
увеличение скорости расчета самих функций с потерей точности для меня не подходит
276
18 мая 2010 года
Rebbit
1.1K / / 01.08.2005
Цитата: Rad87
похоже нужно уменьшать частоту вызова тригонометрических функций и оптимизировать сам алгоритм.
увеличение скорости расчета самих функций с потерей точности для меня не подходит


Совершенно верно.
Может гдето можно схитрить через формулы типа tg = sin/cos и т.п.
Ну и если вы оперируете с небольшим количеством углов, то может стоит сделать некий кеш значений тригонометрических функций. Хотя тут засекать нужно чтоб медленнее не получилось и с розмером кеша играться.

307
18 мая 2010 года
Artem_3A
863 / / 11.04.2008
Rad87,
если вы говорите о том, что по вашей ссылки, то это полный уг, бо пляска с макросами и написание каких то оберток сишных для sse ни когда не будет работать быстрее чем сопроцессор. конечно можно надеяться на всемогущую оптимизацию сишных компиляторов, но и они не боги.

вы профилировали свой код, в смысле человеческим профайлером(к примеру аэмдешным)? возможно у вас затыки основные и не в математике.

что могу посоветовать:
Intel® Math Kernel Library - но это дело платное, есть бесплатный аналог AMD Core Math Library, сам с этими вещами не работал, но вроде как по отзывам они быстрые и крутые, может стоит поискать что то подобное.
может быть вам стоит попробовать реализовать функцию, к примеру, синус через разложение в ряд Тэйлера ручками на sse, а потом посмотреть ее производительность и точность. один мой знакомый тварил такое дело, точность у него упала не значительно(расхождение со стандартной сишной примерно 3%) и то только на больших значения угла, но вот скорость упала раза в два, но делал он это без sse, на базовых инструкциях, вдруг у вас получится лучше и быстрее, в теории это возможно. или банально заюзать сопроцессор, если вы конечно уже это не сделали. реализовывать советую на чистом асме и слинковать с вашим кодом.(использовать yasm или nasm извиняюсь за рекламу уж очень они мне нравятся:D) так же может вам стоит попробовать заюзать ваше приложение под 64 бита, там больший простор для маневров на асме(и по словам сишные компиляторы там просто звереют в оптимизации, хотя не поручусь, сам не проверял).

в общем поэкспериментируйте, результат напишите нам, лично мне будет интересно в целях расширения кругозора.

зы: постом выше я имел в виду это.

зызы: а вообще сложно так о чем то говорить, вы бы задачу свою подробней описали, показали тормозные участки кода и все такое.
5
18 мая 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: Artem_3A
Rad87,
если вы говорите о том, что по вашей ссылки, то это полный уг, бо пляска с макросами и написание каких то оберток сишных для sse ни когда не будет работать быстрее чем сопроцессор


Стандартные тригонометрические функции сейчас (и так было почти всегда) реализованы именно через сопроцессор.
Автору уже намекнули, что нужно произвести мемоизацию запросов. Кстати, еще можно произвести линейную аппроксимацию. Т.е. вычислить синусы и косинусы в некоторых узловых точках а для значений не являющихся узловыми вычислять промежуточные (в соответствии с прямой, проходящей между соседними узлами).

276
19 мая 2010 года
Rebbit
1.1K / / 01.08.2005
Цитата: hardcase
Кстати, еще можно произвести линейную аппроксимацию. Т.е. вычислить синусы и косинусы в некоторых узловых точках а для значений не являющихся узловыми вычислять промежуточные (в соответствии с прямой, проходящей между соседними узлами).


Ну это опять же недопустимая автору потеря точности.
Автор, поделитесь задачей. А возможно и критическими участками кода.

1.9K
19 мая 2010 года
Rad87
123 / / 14.12.2005
при расчете угла наклона ребер и др. элементов фигуры я использовал тригонометрические функции. Сейчас я кэширую результаты. После поворота фигуры ставлю флаг о необходимости пересчитать значения. Скорость работы возросла в несколько раз. :)

так как список закэшированных значений храниться у каждой фигуры свой, поиск по нему происходит быстро.
5
19 мая 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: Rad87

так как список закэшированных значений храниться у каждой фигуры свой, поиск по нему происходит быстро.


Может быть имеет смысл сделать общий кэш?

1.9K
19 мая 2010 года
Rad87
123 / / 14.12.2005
Цитата: hardcase
Может быть имеет смысл сделать общий кэш?


Не... фигуры вращатьются на произвольный угол с любой точностью хоть на 0,000000000000001 градуса. так что хранить все значения в таблице не реально.
а строить кэш один на все фигуры не очень красиво.... ведь в данном случае либо пользователь класса должен знать о кэше либо фигура может знать что ей не положено знать.

307
19 мая 2010 года
Artem_3A
863 / / 11.04.2008
Цитата: Rad87
Не... фигуры вращатьются на произвольный угол с любой точностью хоть на 0,000000000000001 градуса.



простите, а зачем такая точность? космические корабли проектируете? просто в подавляющем большинстве случае в задачах компьютерной графики на этом экономят, все равно пользователь не увидит, что фигура повернулось с ошибкой на несколько сотых, картинку это не испортит, а производительность повысит!!! да и к тому же разве стандартные функции считают с такой точностью???

5
19 мая 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: Rad87
Не... фигуры вращатьются на произвольный угол с любой точностью хоть на 0,000000000000001 градуса. так что хранить все значения в таблице не реально.

Хм, но ведь в какой-то момент времени значения углов могут совпасть.

1.9K
19 мая 2010 года
Rad87
123 / / 14.12.2005
точность нужна высокая, так как алгоритмы верхнего уровня и так живут в условиях некоторой неопределенности из-за того что работают с координатами представленными вещественными числами (double) (например когда точка находиться на одном уровне или чуть ниже другой, а из-за погрешности которая образуется при арифметических операциях оказывается выше)
Согласен, что возможно такая точность и излишнее, но не хочется копить ошибки ещё и на тригонометрических функциях. а пересматривать работу алгоритмов верхнего уровня тоже времени нет)
14
20 мая 2010 года
Phodopus
3.3K / / 19.06.2008
Конечно нужен общий кеш, т.к. совокупная память занятая раздельными кешами очевидно всегда больше (учитываем накладные расходы). И доступ к памяти общего кеша объективно всегда быстрее.
1.9K
20 мая 2010 года
Rad87
123 / / 14.12.2005
Цитата: Phodopus
Конечно нужен общий кеш, т.к. совокупная память занятая раздельными кешами очевидно всегда больше (учитываем накладные расходы). И доступ к памяти общего кеша объективно всегда быстрее.



По памяти согласен. а по скорости не совсем.
Я реализовал так, что фигура хранит расчеты по текущей позиции. То есть как фигура изменяет свое положение, угол наклона, то старые значения удаляются, а новые считаются по запросу на их получение. В итоге закэшированные значения хранятся у фигуры и доступ к ним мгновенен так как там хранятся текущие значения.

Но даже предположить если бы я реализовал это иначе, то я не понимаю как может быть доступ в общем кэше быть быстрее чем в малом? даже по аналогии с кэшем процессора самыми быстрыми являются малые кэщи.

14
20 мая 2010 года
Phodopus
3.3K / / 19.06.2008
Цитата: Rad87
как может быть доступ в общем кэше быть быстрее чем в малом?


Если кеш будет реализован с непрерывной области памяти, вероятность сбоя страницы, из-за бОльшего количества обрашений, будет меньше.

276
20 мая 2010 года
Rebbit
1.1K / / 01.08.2005
Товарищи. Вы о разных вещах говорите.
2Phodopus
Как я понял у него не кеш значений, а значения тригонометрических функций в модель додана.

2Rad87. Я прав? Вы же не держите угол - синус, а просто синусы в модель обекта приклеиваете? Так?
1.9K
20 мая 2010 года
Rad87
123 / / 14.12.2005
Цитата: Rebbit

2Rad87. Я прав? Вы же не держите угол - синус, а просто синусы в модель обекта приклеиваете? Так?


Совершенно верно!!! Если быть точнее то не сами синусы, а результат вычислений с использованием этих синусов и косинусов.

350
25 мая 2010 года
cheburator
589 / / 01.06.2006
Оптимизировать геометрию можно (попробовать) школьным способом.
1. Хранить кэш синусов/косинусов сравнительно больших углов (с шагом в 1').
2. Сравнительно малые углы (менее 1') с ОЧЕНЬ большой точностью равны: синус а = а, косинус а = 1. Тогда (из школьной геометрии sin(a+b) = sina*cosb + cosa*sinb) получаем формулу
sin(a+b) = a*cosb + sinb, где a - "малая" часть угла (остаток от деления на 1'), b - "большая" часть угла (целая часть деления на 1'). Например
sin (134,8776 градусов) = 0,708615746723759, а по приближённой формуле будет 134,86666... градусов и 0,656 минут (это 0,000190822665 радиан), т. е. sin (134,8 градусов) = sin (134,86666... градусов) + 0,000190822665*cos(134,8666... градусов) = 0,708750377261 - 0,000134617634 = 0,708615759627, это я ещё в расчётах использовал 12 знаков и ошибка вышла в 7-м.
Учитывая точность типа double, ошибка после всех вычислений вряд ли будет хуже 10-го знака.
Выбирая хороший шаг таблицы, можно улучшить точность.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог