Всем доброго времени суток!
Вопрос касается оптимизации в DirectX.
Мне часто приходится запускать приложения с 3D графикой на слабых компьютерах, и они ощутимо тормозят. Какие наиболее тормозящие моменты могут быть, и как от них избавиться? можно ли получить значительное ускорение, или максимум что можно сделать это ускорить процентов на 10, что не стоит затраченных усилий?
Я слышал, что найбольшей проблемой является расчет Sin\Cos, и можно создать таблицу с заранее расчитанными значениями. Как в таком случае ее хранить и загружать?
Буду благодарен за ссылки на литературу и информационные ресурсы, желательно рускоязычные.
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
24-02-2009 06:00
Да это же обычная интерполяция. Причём есть куча схем (так называемое взвешенное среднее), напр. F = a*x(N) + b*x(N+1).
AlexSku, а можно поподробнее про этот "табличный метод" с примерами или хотя бы ссыль на материалы по этому вопросу...
Допустим, я сделал саму таблицу значений синуса от -PI/2 до PI/2
А вот как, например, брать значения SIN(х) из таблицы, зная только "х" ??
(Которое к тому же указано в радианах и может равняться любому произвольному числу даже не входящему в промежуток [-PI/2, PI/2])
Обязательно переводить имеющееся значение "х" в градусы?
07-01-2009 09:05 | Комментарий к предыдущим ответам
>>> Порой нужно посмотреть на задачу с другой стороны. Непонятно, зачем при использовании >>> DirectX использовать косинусы?
А игры..... :)
>>> чтобы быстро нарисовать окружность не нужны никакие косинусы - на отрисовку одной точки >>> уходит две операции умножения и одна сложения.
Как это?
1) Писал несколько раз про синусы и косинусы. Есть табличный метод. Он требует памяти и немного уступает по точности тому, что будет ниже. Но в DirectX особая точность не требуется (для экономии памяти используются float простой точности, а не удвоенной).
Есть метод расчёта (через ряд). Памяти не надо, зато время тратится.
Есть промежуточный метод CORDIC. Имеется небольшая таблица, а на каждом шаге выполняются очень простые команды (сложение, сдвиг) и за 16 шагов можно получить 16 разрядов.
На самом деле, используется функция арифметического сопроцессора, а уж что там заложено - мне не известно (не исключено, что CORDIC). Но моя личная проверка показала, что синусы и косинусы считаются очень быстро.
2). Замедление происходит, если расчёты выполняет не видеопроцессор, а главный процессор. Т.е. если нет аппаратного ускорения (или поддержки некоторых параметров. Их можно узнать по Capabilities), то улучшения не произойдёт.
3). Есть небольшое ускорение такого плана. Вместо матриц (4х4 = 16 компонент для перемножения) используются кватернионы (4 компоненты).
Порой нужно посмотреть на задачу с другой стороны. Непонятно, зачем при использовании directX использовать косинусы?
К примеру, чтобы быстро нарисовать окружность не нужны никакие косинусы - на отрисовку одной точки уходит две операции умножения и одна сложения.
Что можно изменить чтобы быстродействие выросло максимально?
- выкинуть все и вся, а в dpr-е написать MessageBox(0,'Hello World','It is kruto',mb_ok).
Вам же уже разжевали, где в Вашей задаче есть резервы... От себя еще добавлю, что рисовать нужно как можно меньше на канве контролов. Т.е. максимально стараться рисовать на битмапах, а потом ОДНИМ методом переносить на канву контрола.
Обычно чтобы узнать что именно тормозит, применяют профилировщики. В них отлично видно какая функция сколько раз вызывается. Еще можно лог попробовать вести.
Сами алгоритмы.
Минимизировать количество вычислений.
Умножения раз в 10 быстрее делений.
Сложения чуть быстрее вычитаний.
Операции с целыми числами на порядок быстрее, чем с плавающими.
Single быстрее Double.
Очень часто чо-то можно не считать каждый раз, а вычислить однажды и подставлять в выражение (как, например с косинусами).
Обычно, на экран пользователя помещается не так много объектов.
Подумайте как отбраковать, те что не будут видны или будут неразличимо мелкими.
Нередко отбраковыванием неиспользуемых частей можно достичь 1000 кратного ускорения.
Ну уж таблицу-то Sin/Cos как сделать ...
Я понимаю бухгалтеру или журналисту не дано, но программисту ...
var
CosArray: array [0..360] of Single;
procedure InitCosTable;
var
i: Integer;
begin
for i := 0 to 360 do
CosArray[i] := Cos(i/180*pi);
end;
function CosFromTable(AngleInRadians: Single): Single;
const
PiTo01Coef = 1/pi/2;
var
Index: Integer;
begin
Index := Round(Frac(Abs(AngleInRadians)*PiTo01Coef)*360);
Result := CosArray[Index];
end;
function SinFromTable(AngleInRadians: Single): Single;
const
PiTo01Coef = 1/pi/2;
Diff = -pi/2;
var
Index: Integer;
begin
Index := Round(Frac(Abs(Diff-AngleInRadians)*PiTo01Coef)*360);
Result := CosArray[Index];
end;
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.