Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.12.2008, 06:51   #1
gusluk
Форумчанин
 
Аватар для gusluk
 
Регистрация: 16.10.2008
Сообщений: 205
По умолчанию оптимизировать для максимальной скорости выполнения программы, т.е. заменить ее кодом на ассемблере

Есть процедура расчета некой функции. На делфи она выглядит так:
Код:
for i:=1 to N do
begin
     for j:=1 to M do
     begin
     if (Fx[i]>KrMin) and (Fx[i]<KrMax) and ((Fx[i]<-MinF)or (Fx[i]>MinF)) then    
     Fx[j]:=Fx[j]+ dx[i,j]*Fx[i];
     end;
Fx[i]:=0;
end;
Хочу ее оптимизировать для максимальной скорости выполнения программы, т.е. заменить ее кодом написанным на ассемблере, для этого начал потихоньку его изучать. Но есть вопрос: а есть ли в этом смысл, реально ли добиться серьезного увеличения скорости выполнения этой функции на ассемблере по сравнению с Delphi 7? И если реально что можете посоветовать по этому поводу?
gusluk вне форума Ответить с цитированием
Старый 04.12.2008, 08:46   #2
airyashov
Форумчанин
 
Регистрация: 02.04.2008
Сообщений: 358
По умолчанию

Для начала можно посмотреть асм код который делфи сделала.
В данном случае, проще разбить цикл на 4(2) потока, 4(2) ядра в помощь, никая оптимизация на ассемблере не даст выигрыш 3/4 времени из-за сложной адресации элементов массивов, хотя процентов 15-30% можно получить переписав все на fpu вручную.
неплохо пишу на ассемблере для 80х86
icq: 3(один)7748666
mail: airyashov(а)inbox.ru
airyashov вне форума Ответить с цитированием
Старый 04.12.2008, 14:44   #3
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Может сначала попробовать оптимизировать в Delphi. Например:

Код:
   for i:=1 to N do begin
      // условие, похоже зависит только от i (кроме одного случая)
      // если условие не выполняется нет смысла выполнять внутренний цикл
      B := (Fx[i]>KrMin) and (Fx[i]<KrMax) and ((Fx[i]<-MinF)or (Fx[i]>MinF));
      if B then begin
         for j:=1 to M do begin

            Fx[j]:=Fx[j]+ dx[i,j]*Fx[i];

            if j = i then begin
               // А здесь условие может поменяться
               // вычисляем его заново
               B := (Fx[i]>KrMin) and (Fx[i]<KrMax) and ((Fx[i]<-MinF)or (Fx[i]>MinF));
               // И опять если условие не выполняется нет смысла продолжать
               if not B then break;
            end;

         end;
      end;
      Fx[i]:=0;
   end;
Конечно, если KrMin, KrMax, MinF - это константы, а не функции с побочными эффектами.
alexBlack вне форума Ответить с цитированием
Старый 05.12.2008, 04:02   #4
gusluk
Форумчанин
 
Аватар для gusluk
 
Регистрация: 16.10.2008
Сообщений: 205
По умолчанию

К сожалению асм код делфи для этой функции пока показать не могу, программа еще не дописана, но есть почти точно такая же функция которую я делал для проверки алгоритма, и позже его попробую выложить.
airyashov, что ты имел в виду когда сказал что проще разбить цикл на 4(2) потока? Я просто пихал этот цикл в два потока, т.к. машина двух ядерная, на никак его не разбивал.
alexBlack, спасибо, я тоже уже думал оптимизировать его на делфи, но сначала хотел узнать на сколько его можно оптимизировать на асм.
KrMin, KrMax, MinF задаются с исходными данными, и в процессе вычислений не меняются.
gusluk вне форума Ответить с цитированием
Старый 05.12.2008, 05:06   #5
gusluk
Форумчанин
 
Аватар для gusluk
 
Регистрация: 16.10.2008
Сообщений: 205
По умолчанию

Проанализировал асм код делфи, пришел к выводу что больше чем на 20% его не ускорить. В итоге решил его сначало оптимизировать как предложил
alexBlack. Посмотреть как его с компилирует делфи,и если будет возможность увеличить его производительность более чем на 30% то переписать на ассемблере, и пихнуть в два потока. Как вы считаете, это наиболее подходящий вариант, или можно что то получше придумать?
gusluk вне форума Ответить с цитированием
Старый 05.12.2008, 06:06   #6
gusluk
Форумчанин
 
Аватар для gusluk
 
Регистрация: 16.10.2008
Сообщений: 205
По умолчанию

Вот пример функции в делфи:
Код:
for i:=1 to 90 do
begin
     for j:=1 to 100 do
     begin
     if (Ln[i]>-5000) and (Ln[i]<5000) and ((Ln[i]<-1)or  (Ln[i]>1)) then Ln[j]:=Ln[j]+ Lsin[i,j]*Ln[i];

     end;
     Ln[i]:=0;
end;
и асм:
Код:
for i:=1 to 90 do
mov [ecx],$00000001
for j:=1 to 100 do
mov [ebx],$00000001
 if (Ln[i]>-5000) and (Ln[i]<5000) and ((Ln[i]<-1)or  (Ln[i]>1)) then Ln[j]:=Ln[j]+ Lsin[i,j]*Ln[i];
mov eax,[ecx]
fld qword ptr [$004523d0]
fstsw ax
sahf
jbe +$58
mov eax,[ecx]
fld qword ptr [edx+eax*8-$08]
fcomp dword ptr [$004523d4]
fstsw ax
sahf
jnb +$47
mov eax,[ecx]
fld qword ptr [edx+eax*8-$08]
fcomp dword ptr [$004523d8]
fstsw ax
sahf
jb +$11
mov eax,[ecx]
fld qword ptr [edx+eax*8-$08]
fcomp dword ptr [$004523dc]
fstsw ax
sahf
jbe +$25
imul eax,[ecx],$000003e8
lea eax,[esi+eax*8]
mov edi,[ebx]
fld qword ptr [eax+edi*8-$00001f48]
mov eax,[ecx]
fmul qword ptr [edx+eax*8-$08]
mov eax,[ebx]
fadd qword ptr [edx+eax*8-$08]
mov eax,[ebx]
fstp qword ptr [edx+eax*8-$08]
wait
end;
inc dword ptr [ebx]
for j:=1 to 100 do
cmp dword ptr [ebx],$65
jnz -$70
Ln[i]:=0;
mov eax,[ecx]
xor edi,edi
mov [edx+eax*8-$08],edi
mov [edx+eax*8-$04],edi
end;
inc dword ptr [ecx]
for i:=1 to 90 do
cmp dword ptr [ecx],$5b
jnz -$0000008d
end;
pop edi
pop esi
pop ebx
ret
add [eax],al
inc eax
pushfd
ids eax, [eax]
inc eax
pushfd
inc ebp
add [eax],al
cmp byte ptr [edi+$3f800000],$53
push esi
push edi
mov edx, $004590d0
mov ecx, $0139d4d8
mov ebx, $0139d4dc
mov esi,$00bfc210

Последний раз редактировалось gusluk; 05.12.2008 в 06:09.
gusluk вне форума Ответить с цитированием
Старый 10.12.2008, 04:21   #7
gusluk
Форумчанин
 
Аватар для gusluk
 
Регистрация: 16.10.2008
Сообщений: 205
По умолчанию

Странно, но вариант предложенный alexBlack дал выигрыш по времени около 20% , я ожидал большего. Попозже попробую выложить его асм код.
gusluk вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Можно ли ввести данные в таблицу StringGrid не в процессе выполнения программы а заранее Arassir Помощь студентам 5 02.11.2008 17:34
нужна помощь в написании программы на ассемблере marsela Помощь студентам 4 25.04.2008 21:42
Приостановка цикла для выполнения внешней программы Uomo Общие вопросы Delphi 3 04.04.2008 11:48
Программы с открытым кодом Hallo Свободное общение 10 31.05.2007 07:46