Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

оптимизация: что быстрее? [D5, WinXP]


Страницы:   1 2

tButton ©   (2006-06-09 06:14:00) 

a*2или a+a, если a: real;?
(сие творится многократно в ходе цикла и потому выбор более быстровыполняемого действия очень важен)


ЮЮ   (2006-06-09 11:49:00) [21]


> 5-7 тысяч частиц
> т.е. больших нагрузок на память не предполагается


При таком количестве частиц надо оптимизировать сам алгоритм, а не время вычислений на одном цикле итерации, ибо:

procedure TForm1.Button1Click(Sender: TObject);
var
 a: Extended;
 i, j, n: integer;
 start: Cardinal;
begin
 n := 5000;
 a := 0;
 Start := GetTickCount;
 for i := 1 to n  do
   for j := 1 to n do begin
     a := a + 1/i ;
     //a := a + 1/j;
   end;
 Button1.Caption := IntToStr(GetTickCount - Start);
 Caption := FloatToStr(a);
end;


Теперь оцени время на выполнение только одной строки.
А теперь раскомментируй вторую.
А ты ещё мечтаешь о сложных рассчетах.


palva   (2006-06-09 11:47:00) [22]

Я бы не корпел над оптимизацией исходного кода, а писал бы формулы максимально понятно для постороннего специалиста-непрограммиста. Только написал бы вычислительное ядро на си. А уж Borland Compiller оптимизирует, как надо. По моему опыту, будет работать заметно быстрее.


tButton   (2006-06-09 11:07:00) [23]


> Но, естественно, при условии что нет жестких ограничений
> по объему занимаемой этими переменными памяти приложения.

пока приложение использует около 48 байт на частицу системы
стандартная система - 1000 частиц
предельный размер (не дающий уснуть в ожидании отрисовки очередного кадра) 5-7 тысяч частиц
т.е. больших нагрузок на память не предполагается

> Если производительность алгоритма столь важна,

просто необычано важна

> MMX/SIMD/SSE-расширениям ?

признаться, знакомо только слово MMX

> Или воспользоваться готовыми библиотеками, эффективно использующими
> эти расширения

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


Kolan   (2006-06-09 11:07:00) [24]

От Real вообще надо отказаться.. ИМХО это из паскаля осталось


Сергей М.   (2006-06-09 10:58:00) [25]


> имеет смысл отказаться от типа real в пользу extended?


Да.
Но, естественно, при условии что нет жестких ограничений по объему занимаемой этими переменными памяти приложения.

Если производительность алгоритма столь важна, может быть стоит присмотреться к MMX/SIMD/SSE-расширениям ? Или воспользоваться готовыми библиотеками, эффективно использующими эти расширения, а-ля Intel Math Kernel Library ?


tButton   (2006-06-09 10:48:00) [26]


> Сергей М. ©   (09.06.06 10:04) [11]

т.е. имеет смысл отказаться от типа real в пользу extended?

> Ты бы побольше информации про подлежащий оптимизации код
> привел...

могу. код из моего текущего проекта, там просто уйма вычислений и все с числами с плавающей точкой
вот один из методов объекта реализующего систему взаимопритягивающихся частиц
for i:=0 to high(pts) do
   for j:=0 to high(pts) do
   begin
     // i - индекс обрабатываемой точки
     // j - индекс точки к которой притягиваемся
     if i=j then continue; // сами на себя не воздействуем
     dx:=pts[j].x-pts[i].x; // конечная минус начальная
     dy:=pts[j].y-pts[i].y;
      g:=Gravity(pts[i], pts[j]);
     v:=sqrt(2*g/pts[i].m);
      d:=Dist(pts[i], pts[j]);
     vx:=dx/d;
     vy:=dy/d;
     vx:=vx*v;
     vy:=vy*v;
     pts[i].vx:=pts[i].vx+vx*quarq;
     pts[i].vy:=pts[i].vy+vy*quarq;
   end;

наработки по оптимизации
high(pts) присвоить переменной и использовать её в цикле вместо постоянного обращения к функии
d:=Dist(pts[i], pts[j]); заменить на sqrt(dx*dx+dy*dy). потому что процедура вычисляет dx и dy по новой

g:=Gravity(pts[i], pts[j]); здесь тоже используется рассчёт дистанции, поэтому есть повод отказаться от процедуры

vx:=dx/d; и vx:=vx*v; можно заменить на d:=v/d;и vx:=dx*d;одной строчкой меньше

v:=sqrt(2*g/pts[i].m); а это то с чего началось, можно объединить с формулой g:=Gravity(pts[i], pts[j]);и упростить.

полный сорц
http://slil.ru/22822987
екзешник
http://slil.ru/22822989


Сергей М.   (2006-06-09 10:04:00) [27]

Выдержки из мануала IA-32:

FLD—Load Floating Point Value
Description
Pushes the source operand onto the FPU register stack. The source operand can be in single-precision,
double-precision, or double extended-precision floating-point format. If the source
operand is in single-precision or double-precision floating-point format, it is automatically
converted to the double extended-precision floating-point format before being pushed on the
stack.

FST/FSTP—Store Floating Point Value
If the destination size is single-precision or double-precision, the significand of the value being
stored is rounded to the width of the destination (according to rounding mode specified by the
RC field of the FPU control word), and the exponent is converted to the width and bias of the
destination format.

Тоже самое касается инструкций FADD/FMUL, если операнд берется из памяти.


MBo   (2006-06-09 09:55:00) [28]

>tButton
Ты бы побольше информации про подлежащий оптимизации код привел...


tButton   (2006-06-09 09:50:00) [29]


> т.к. при этом для Real-типа всякий раз происходит прямое
> и обратное преобразование между Real и Extended.

а можно про это чуть подробнее?


Сергей М.   (2006-06-09 09:48:00) [30]


> tButton ©   (09.06.06 06:14)


Отличие
 a := a+a;
от
 a := a*2;

всего в одной маш.инструкции - в 1-м случае fadd, а во 2-м fmul

Cовременные FPU выполняют умножение практически столь же быстро, как и сложение, так что ловить здесь блох нет повода ... Лучше будет сосредоточить внимание на оптимальность "подготовительных" операций: загрузку операндов и выгрузку результата - они ощутимо больше влияют на сквозную производительность алгоритма, т.к. при этом для Real-типа всякий раз происходит прямое и обратное преобразование между Real и Extended.


MBo   (2006-06-09 09:11:00) [31]

Unit3.pas.35: b:= a shl 3;
00455ABB 8BDA             mov ebx,edx
00455ABD 03DB             add ebx,ebx
00455ABF 03DB             add ebx,ebx
00455AC1 03DB             add ebx,ebx

а начиная с shl 4 - уже сдвигом
В любом случае накладные расходы на сам цикл в несколько раз больше, чем на эту арифметику


tButton   (2006-06-09 08:55:00) [32]

хы =)
а shl 2?)


MBo   (2006-06-09 08:53:00) [33]

> я бы смело пользовался shl 1

приколись:

Unit3.pas.35: b:= a shl 1;
00455ABB 8BDA             mov ebx,edx
00455ABD 03DB             add ebx,ebx

:)


tButton   (2006-06-09 08:44:00) [34]

ну, ежели б тут были целые беззнаковые, я бы смело пользовался shl 1 или бы множил на 2 (компилятор сам заменит умножение на степень двойки на shl)
но тут, блин действительные числа... помнится, в процессоре Pentium MMX, был давже встроеный сопроцессор, для операций над числами с плавающей запятой (или это мой склероз надо мной стебается?)


Urvin   (2006-06-09 08:03:00) [35]

кажись операция сложения всегда выполнялась быстрее


tButton   (2006-06-09 06:58:00) [36]


> Проверь :)

проверю =)
но это ещё до дому дойти надо =)


MBo   (2006-06-09 06:39:00) [37]

Проверь :)


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо