Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2007.04.08;
Скачать: [xml.tar.bz2];

Вниз

Сижу, как столица одного из государств Азии...   Найти похожие ветки 

 
ProgRAMmer Dimonych ©   (2007-03-13 16:23) [0]

Попросил тут один человек отладить маленько программу, чтобы работала быстрее.

Первым делом, конечно, позаменял все Exp(a*Ln(2)) на отдельную переменную, в которую значение этого выражения вычисляется один раз, а потом раза три используется. Ну, и ещё слегка пооптимизировал - выиграл в среднем в 2 раза.

В поисках, чего бы ещё наоптимизировать, вспомнил о том, что говорил нам в своё время один уважаемый человек на сборах по подготовке к Республиканской олимпиаде: вместо использования Ln лучше сгенерировать самому в массив степени двойки и их использовать.

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

RealA:=1;
for a:=1 to pp do
begin
 Inc(RealA,RealA);
 StringGrid1.Cells[a,0]:="a="+IntToStr(RealA);
 for b:=0 to m-1 do
 begin
  W_a_b:=0;
  for i:=0 to m-1 do
  begin
   Delta_T:=X[2].Time-X[1].Time;
   Ti:=i*Delta_T;
   Ti2:=Ti*Ti;
   W_a_b:=W_a_b+Sqrt(Delta_T/RealA)*X[b].Value*(1-Ti2)*Exp(-Ti2/2)*(Ti-b)/RealA*Delta_T;
  end;
  StringGrid1.Cells[0,b+1]:="b="+IntToStr(b+1);
  StringGrid1.Cells[a,b+1]:=FloatToStr(W_a_b);
 end;
end;

Вот такой вот код. Все переменные объявлены соответствующим образом. Вместо Inc(RealA,RealA) первоначально использовалось RealA:=RealA*2. IntToStr в самом первом (совсем неоптимизированном) варианте выглядели, как FloatToStr, хотя по логике приложения IntToStr уместнее, да и работать должна быстрее.

Внимание, вопрос!!! Объясните мне тёмному, почему
1) RealA:=Exp(a*Ln(2)) работает быстрее, чем мой вариант?
2) Почему замена FloatToStr на IntToStr замедлила работу программы?


 
alien1769 ©   (2007-03-13 16:26) [1]

Хотя бы версию дельфи дал и режим компиляции


 
ProgRAMmer Dimonych ©   (2007-03-13 16:32) [2]

> alien1769 ©   (13.03.07 16:26) [1]
Даю: Delphi 7.
Настройки компилятора...

<Создание кода>
Оптимизация=True
Фреймы стека=False
Pentium safe FDIV=False
Запись полной привязки=8
</Создание кода>
<Ошибки выполнения>
Проверка диапазона=False
Проверка I/O=True
Проверка переполнения=False
</Ошибки выполнения>
<Отладка>
Инфо отладки=True
Локальные символы=True
Инфо ссылки=True
Только Определения=True
Утверждения=True
Использовать DCU отладки=False
</Отладка>

P.S. Вот такой кривой перевод (локализация) Delphi...


 
Ketmar ©   (2007-03-13 16:32) [3]

есть подозрение, оформлю как хинт: преобразования форматов.


 
Ketmar ©   (2007-03-13 16:33) [4]

это не "локализация". это "дебилизация".


 
ProgRAMmer Dimonych ©   (2007-03-13 16:34) [5]

> Ketmar ©   (13.03.07 16:32) [3]
Знаковый-беззнаковый, Целый-Плавающий. Это это?


 
SlymRO ©   (2007-03-13 16:34) [6]

ProgRAMmer Dimonych ©   (13.03.07 16:23)
RealA:=RealA*2

быстрее... т.к. сдвиг это раз, два (непомню inc инлайнится или нет) inc вызов процедуры...


 
ProgRAMmer Dimonych ©   (2007-03-13 16:35) [7]

> SlymRO ©   (13.03.07 16:34) [6]
Но по сравнению с Exp(a*Ln(2)) даёт худший результат: потери от 10-15 мс на небольших m до 1000-1500 на m>1000. :(


 
SlymRO ©   (2007-03-13 16:37) [8]

ProgRAMmer Dimonych ©   (13.03.07 16:23)
Delta_T:=X[2].Time-X[1].Time;

vj;yj dsxbckbnm jlby hfp&
можно вычислить один раз?


 
SlymRO ©   (2007-03-13 16:40) [9]

RealA:=RealA shl 1;


 
ProgRAMmer Dimonych ©   (2007-03-13 16:46) [10]

> SlymRO ©   (13.03.07 16:37) [8]
> ProgRAMmer Dimonych ©   (13.03.07 16:23)
> Delta_T:=X[2].Time-X[1].Time;
> vj;yj dsxbckbnm jlby hfp&
> можно вычислить один раз?
Вот, блин... Слона-то я и не заметил. Надо только уточнить, не очепятка ли это у автора проги...

> SlymRO ©   (13.03.07 16:40) [9]
> RealA:=RealA shl 1;
Попробую как дополнительную оптимизацию... Хотя, кажется, разница на современных процессорах будет максимум такта 2 (mul выполняется за 1 такт для большинства типов операндов - регистр, память, immediate - а переменная - Integer).

В любом случае огромное спасибо.


 
SlymRO ©   (2007-03-13 16:49) [11]

Ti:=i*Delta_T;
Ti2:=Ti*Ti;
*(1-Ti2)*Exp(-Ti2/2)*
зависит от i, и вычисляется одно и тоже m раз
Загони их в массив и пользуй


 
SlymRO ©   (2007-03-13 17:03) [12]

var cached_Ti2:array of extended;
begin

 Delta_T:=X[2].Time-X[1].Time;
 SetLength(cached_Ti2,m);
 for i:=0 to m-1 do
 begin
   Ti:=i*Delta_T;
   Ti2:=Ti*Ti;
   cached_Ti2[i]:=(1-Ti2)*Exp(-Ti2/2);
 end;

 RealA:=1;
 for a:=1 to pp do
 begin
   RealA:=RealA shl 1;
   StringGrid1.Cells[a,0]:="a="+IntToStr(RealA);

   for b:=0 to m-1 do
   begin
     W_a_b:=0;
     for i:=0 to m-1 do
     begin
      Ti:=i*Delta_T;
      W_a_b:=W_a_b+Sqrt(Delta_T/RealA)*X[b].Value*cached_Ti2[i]*(Ti-b)/RealA*Delta_T;
     end;
     StringGrid1.Cells[0,b+1]:="b="+IntToStr(b+1);
     StringGrid1.Cells[a,b+1]:=FloatToStr(W_a_b);
   end;
 end;
end;


 
Jeer ©   (2007-03-13 17:12) [13]

sqrt(dT/R)/R*dT == sqrt(R/dT)


 
SlymRO ©   (2007-03-13 17:14) [14]

Jeer ©   (13.03.07 17:12) [13]
ааа!!! не заметил! пипец однако пошел спать...


 
Jeer ©   (2007-03-13 17:16) [15]

Нет, сбрехал.
Но формула странная - зачем нам степени 1.5 ?


 
SlymRO ©   (2007-03-14 04:04) [16]

Ti:=i*Delta_T;
DeltaT_RealA:=Delta_T/RealA;
W_a_b:=W_a_b+DeltaT_RealA*Sqrt(DeltaT_RealA)*X[b].Value*cached_Ti2[i]*(Ti-b);


 
SlymRO ©   (2007-03-14 04:06) [17]

Автар, спидап наблюдается?


 
TUser ©   (2007-03-14 06:07) [18]

> inc вызов процедуры...

Одна команда (inc/add). D7.


 
SlymRO ©   (2007-03-14 06:47) [19]

TUser ©   (14.03.07 6:07) [18]
Одна команда

На то я предварительно отбрехался "(непомню inc инлайнится или нет)"
значит таки инлайнится


 
TUser ©   (2007-03-14 07:01) [20]

Что значит инлапйнится или нет? А оператор for инлайнится? Конпилятор видит этот for и генерирует в этом месте соответствующий код. А когда видит inc/dec/write/... - то тоже генерирует. Что с того, что синтаксис похож на вызов procedure Inc (var A: ...; B: .... = ...); overload;? Нету такой процедуры и нигде в библиотеках она не описана. Это просто замена оператору присвоения. Или := - это тоже inline-procedure?


 
SlymRO ©   (2007-03-14 07:16) [21]

Под инлайном имею ввиду, что процедура (синтаксическая) компилируется не в call inc а в содержимое это процедуры inc какойто_регистр...



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2007.04.08;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.052 c
15-1173543352
Desdechado
2007-03-10 19:15
2007.04.08
Чай и наше здоровье


9-1146876433
TDummyCube
2006-05-06 04:47
2007.04.08
Как найти локальную матрицу, если есть две глобальные?


1-1171563295
Алексей С.
2007-02-15 21:14
2007.04.08
Предпросмотр печати


15-1173901069
default
2007-03-14 22:37
2007.04.08
Alcohol52%


1-1171335655
Андрей Прокофьев
2007-02-13 06:00
2007.04.08
TMemo, TDBMemo





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский