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

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

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 02.01.2008, 13:41   #1
prizrak1390
-=PriZraK=-
Форумчанин
 
Аватар для prizrak1390
 
Регистрация: 12.12.2007
Сообщений: 399
Сообщение Возможно ли такое...если да то как это сделать?!

Еслть ли способ ускорить работу цикла в несколько раз используя Assembler-овские вставки?! Я вроде где-то про такое читал, но листинга не видел( Может тут кто нить сталкивался с проблемой, когда необходимо ускорить работу огромного цикла?! Если кто нить знает или имеет под рукой код ПОМОГИТЕ!!!!!!!!!!!!!!
prizrak1390 вне форума Ответить с цитированием
Старый 02.01.2008, 14:02   #2
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

Тю, так выложи свой код
пыщь
JTG вне форума Ответить с цитированием
Старый 02.01.2008, 14:06   #3
prizrak1390
-=PriZraK=-
Форумчанин
 
Аватар для prizrak1390
 
Регистрация: 12.12.2007
Сообщений: 399
По умолчанию

repeat
if ac='on' then begin
application.ProcessMessages;
end;
if form4.CheckBox6.Checked=true then begin {фазовый контроль потока}
c:=max div 2;
cc:=max div 4;
if num=cc then application.ProcessMessages;
if num=c then application.ProcessMessages;
end;
form1.Caption:='Please wait...'+inttostr(progressbar1.Posi tion)+'\'+inttostr(progressbar1.Max )+'\'+inttostr(form3.Gauge1.Percent Done)+'%';
num:=num+1;
progressbar1.Position:=num;
form3.Gauge1.Progress:=num;
form3.Label1.Caption:='PIXEL:'+intt ostr(form3.Gauge1.Progress);
sis:=sis+1;
inc(i);
progressbar2.Position:=i;
image1.Canvas.Pixels[i,ii];
if image1.Canvas.Pixels[i,ii]=-1 then begin
i:=0;
inc(ii);
end;
memo2.Lines.Add(inttostr(image1.Can vas.Pixels[i,ii]div com));
memo2.Color:=image1.Canvas.Pixels[i,ii];
if form4.CheckBox7.Checked=true then
image1.Canvas.Pixels[i,ii]:=clskyblue;
label1.Caption:='Скорость ['+inttostr(sis2)+'] в сек.';
{until ii=image1.Width; }
if i=progressbar1.Max-1 then exit;
until i=progressbar1.Max-1;

Вот его надо жестоко ускорить
prizrak1390 вне форума Ответить с цитированием
Старый 02.01.2008, 14:13   #4
prizrak1390
-=PriZraK=-
Форумчанин
 
Аватар для prizrak1390
 
Регистрация: 12.12.2007
Сообщений: 399
По умолчанию

вот в кратце суть...
Мы по 1-му анализируем изображение(тупо берем цвет пиксела с позиции I и заносим его цвет в Memo...) так вот, если не использовать Application.processMess... то вся программа на время умирает, а как цикл завершен программа снова оживает, но при использовании Application.Process... теряю жестоко скорость. Заметил то, что при повторном анализе одного и того же изображения, я получаю скорость до 16-тысяч пикселов в секунду, а обычно скорость 450-500 пикселов в секунду....может картинку сначало как нить надо в память занести, но я не знаю как мне этот сделать, вот и прошу помочь ускорить это цикл используя Асемблеровские вставки)

Я знаю что не рационально так брать цвет пикселов, что этот поход просто ужасен. Но я только недавно начал работать с Canvas, могу только таким примитивным циклом брать цвет...
prizrak1390 вне форума Ответить с цитированием
Старый 02.01.2008, 15:23   #5
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

Код:
var pbmax:integer;
         f4cb7_checked, :boolean;

pbmax:=progressbar1.Max;
f4cb7_checked:=form4.CheckBox7.Checked;

repeat
  if ac='on' then application.ProcessMessages;

  if  f4cb7_checked then 
  begin {фазовый контроль потока}
    c:=max div 2;
    cc:=max div 4;
    if (num=cc) or (num=c) and (ac<>'on') then application.ProcessMessages;
  end;

  {это можно заменить на API ф-цию wsprintf}
  form1.Caption:='Please wait...'+inttostr(progressbar1.Position)+'\'+intto str(pbMax)+'\'+inttostr(form3.Gauge1.PercentDone)+'%';

  inc(num);
  progressbar1.Position:=num;
  form3.Gauge1.Progress:=num;
  form3.Label1.Caption:='PIXEL:'+inttostr(form3.Gauge1.Progress);
  inc(sis);
  inc(i);

  progressbar2.Position:=i;

  image1.Canvas.Pixels[i,ii];
  if image1.Canvas.Pixels[i,ii]=-1 then begin
    i:=0;
    inc(ii);
  end;

  memo2.Lines.Add(inttostr(image1.Canvas.Pixels[i,ii]div com));
  memo2.Color:=image1.Canvas.Pixels[i,ii];

  if f4cb7_checked then image1.Canvas.Pixels[i,ii]:=clskyblue; {выше уже проверялось это условие, может туда переместить?}

  label1.Caption:='Скорость ['+inttostr(sis2)+'] в сек.';
  {until ii=image1.Width; }
  if i=progressbar1.Max-1 then exit; {ХЗ зачем это}
until i=progressbar1.Max-1;
- Основные тормоза действительно из-за Application.ProcessMessages, может есть смысл вызывать её скажем 1 раз на 10 итераций.
- TGauge отрисовывается на порядок быстрее, чем TProgressBar

Вот ещё немного облегчённая версия IntToStr
Код:
function Int2Str(Value: Integer): String; // http://bonanzas.rinet.ru
asm
	XOR	ECX, ECX
	PUSH	ECX
	ADD	ESP, -0Ch
	PUSH	EBX
	LEA	EBX, [ESP + 15 + 4]
	PUSH	EDX
	CMP	EAX, ECX
	PUSHFD
	JGE	@@1
	NEG	EAX
  @@1:
	MOV	CL, 10
  @@2:
	DEC	EBX
	XOR	EDX, EDX
	DIV	ECX
	ADD	DL, 30h
	MOV	[EBX], DL
	TEST	EAX, EAX
	JNZ	@@2
	POPFD
	JGE	@@3
	DEC	EBX
	MOV	BYTE PTR [EBX], '-'
  @@3:
	POP	EAX
	MOV	EDX, EBX
	CALL	System.@LStrFromPChar
	POP	EBX
	ADD	ESP, 10h
end;
пыщь

Последний раз редактировалось JTG; 02.01.2008 в 15:35.
JTG вне форума Ответить с цитированием
Старый 02.01.2008, 16:05   #6
prizrak1390
-=PriZraK=-
Форумчанин
 
Аватар для prizrak1390
 
Регистрация: 12.12.2007
Сообщений: 399
По умолчанию

"- TGauge отрисовывается на порядок быстрее, чем TProgressBar" - учту это)
Спасибо за Ваш вариант цикла попробую его) а всё таки говорят что есть какие-то общие приёмы на Асемблере, которые ускоряют работу циклов...вот мне чисто интересно было бы узнать возможно ли это?!
prizrak1390 вне форума Ответить с цитированием
Старый 02.01.2008, 16:09   #7
prizrak1390
-=PriZraK=-
Форумчанин
 
Аватар для prizrak1390
 
Регистрация: 12.12.2007
Сообщений: 399
По умолчанию

if i=progressbar1.Max-1 then exit; {ХЗ зачем это} - А затем, что когда цикл завершался, программа оставалась недоступна....просто никак не реагировала, а вот после внедрения дополнительной точки прерывания цикла, проблема исчезла))))
prizrak1390 вне форума Ответить с цитированием
Старый 02.01.2008, 16:20   #8
prizrak1390
-=PriZraK=-
Форумчанин
 
Аватар для prizrak1390
 
Регистрация: 12.12.2007
Сообщений: 399
По умолчанию

Не знаю будет ли Вам это интересно, но я сравнил скорость работы Вашего варианта цикла и моего.
Мой цикл за секунду в среднем обрабатывает 200+-3 пикселей
Ваш цикл за секунду в среднем обрабатывает 180-182 пикселя...
Видимо цикл никак нельзя ускорить без использования Assembler
Спасибо за Вашу помощь
prizrak1390 вне форума Ответить с цитированием
Старый 02.01.2008, 20:50   #9
Jeni
Форумчанин
 
Регистрация: 31.05.2007
Сообщений: 486
По умолчанию

Почти любой алгоритм (и конечно циклы) можно значительно ускорить и без использования ассемблера за счет алгоритмической оптимизации. Что касается конкретно этого алгоритма, то есть несколько возможностей:
1. Переменная max не меняется в цикле. Тогда c и сс можно вычислить заранее.
2. Переменная ac тоже не меняется и условие ac='on' известно до цикла, его можно вычислить предварительно и сохранить как переменную. Тем более что сравнение срок гораздо медленнее, чем целых чисел.
3. Всякие CheckBox.Checked и ProgressBar.Max тоже нужно вычислить до цикла, потому что свойства читаются/записываются медленнее, чем обычные переменные (тем более многие свойства это на самом деле вызовы функций/процедур).
4. Очень много времени занимает выполнение операций Caption:='...'. Делать это в цикле, да еще в каждой итерации, не стоит, лучше просто перед циклом сделать надпись типа "Идет рассчет...", а уже после цикла дописать "окончание".
5. Действительно нужно записывать в memo ВСЕ значения? Это довольно длительная операция. Может стоит записывать только НУЖНЫЕ?
6. Операция чтения пикселя Canvas.Pixels[i,ii] дважды встречается по два раза. Лучше записать в переменную и уже её использовать.
Ну и ещё кое-что по-мелочи...

А вообще, лучше просто переделать алгоритм. Например, использовать ScanLine для доступа к пикселям.
Jeni вне форума Ответить с цитированием
Старый 03.01.2008, 10:14   #10
prizrak1390
-=PriZraK=-
Форумчанин
 
Аватар для prizrak1390
 
Регистрация: 12.12.2007
Сообщений: 399
По умолчанию

да я конечно использовал бы что нибудь другое, но ScanLine пользоваться не умею
prizrak1390 вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Возможно реализовать такое Devourer12345 Microsoft Office Access 10 15.08.2008 08:08
Как возможно сделать изменение кнопки xGroupers Общие вопросы Delphi 4 25.04.2008 00:07
Возможно ли такое? (Программирование станка) Az_ Микроконтроллеры, робототехника, схемотехника, 3D принтеры 4 07.04.2008 07:30
то такое мастерство в программировании, что такое мастер программист и что он может? Cezar Свободное общение 29 02.06.2007 23:48
как удалить анти вирус( касперский 2006)если она не работает и ее не возможно удалить Alar Общие вопросы Delphi 0 29.10.2006 21:36