Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.ru

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

Как ускорить ход? [Delphi, Windows]


XNA   (04.03.13 14:30

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

Как его ускорить, оптимизировать, развернуть циклы и т.д.?
Если изображение 32-bpp?


procedure DummyFX(Bmp: TBitmap);
var
 P   : PRGBA;     // Или TRGBQuad.
 X, Y: LongInt;
begin
 For Y:= 0 to Bmp.Height - 1 do
 begin
   P:= Bmp.Scanline[Y];
   For X:= 0 to Bmp.Width - 1 do
   begin
     P.R:= 255; // Что-то делаем.
     P.G:= 0;
     P.B:= 30;
     P.A:= 30;

     Inc(P);
   end;
 end;
end;


XNA   (04.03.13 14:34[1]

* Как ускорить ход?

Как ускорить код обработки всех пикселей?


MBo ©   (04.03.13 14:40[2]

Например, использовать SSE/MMX + проверить, эффективно ли будет развернуть циклы


RWolf ©   (04.03.13 14:49[3]

распараллелить на несколько потоков.


MBo ©   (04.03.13 16:43[4]

Ещё применение CUDA/ OpenCL можно рассмотреть


XNA   (05.03.13 04:11[5]

> MBo ©   (04.03.13 14:40) [2]

Может еще есть какие варианты?


MBo ©   (05.03.13 05:36[6]

Зависит от:
// Что-то делаем.


XNA   (05.03.13 14:02[7]

> MBo ©   (05.03.13 05:36) [6]
> Зависит от:

Т.е. сам перебор всех пикселей не оптимизировать?
Может ещё тормозить TBitmap, знаю внутри он не оптимален.


MBo ©   (05.03.13 15:43[8]

>Может ещё тормозить TBitmap, знаю внутри он не оптимален.
Небольшое время расходуется на получение ScanLine, но на фоне времени обработки самой строки им обычно можно пренебречь. Если очень хочется, то можно получить адрес первой строки и смещение строк (оно обычно отрицательное) и работать как с обычным куском памяти.


Павиа   (06.03.13 16:18[9]

Bmp.Width - обращается к методу, что тормозит вложенный цикл. Заменяем на локальную переменную.
P:= Bmp.Scanline[Y]; - хотя тоже тормозит, но вызывается в Bmp.Width раз меньше.

For заменяем на repeat until.
Раскрутка цикла.  
Но обычно это всё копейки ,так как то что внутри занимает раз в 10-100 больше времени.  Остаётся только распараллеливание задачи.


MBo ©   (06.03.13 16:35[10]

>Bmp.Width - обращается к методу, что тормозит вложенный цикл. Заменяем на локальную переменную.

Не нужно


XNA   (12.03.13 06:54[11]

GetScanline - неимоверно тяжелая функция!

DIBNeeded, где CopyBitmap.
GDIFlush.
Высчитывает BytesPerScanline, который можно рассчитать заранее.

Закоментил первые и ничего не вылетало и продолжает работать!
Но как сделать без правки VCL?
В потомке нельзя перекрыть метод GetScanline.

Как быть?


MBo ©   (12.03.13 08:19[12]

>GetScanline - неимоверно тяжелая функция!
Она что, тратит время, сравнимое с обработкой строки?

Вот библиотека попиксельного доступа:
http://www.delphimaster.ru/articles/pixels/index.html
Однако она на каждом шаге вычисляет адрес пикселов. При произвольных обращениях к разным местам картинки QPixels работает быстрее сканлайна. При последовательной обработке строк чуть быстрее сканлайн.


RWolf ©   (12.03.13 09:33[13]


> Как быть?

не вызывать GetScanline, вычислять указатели самостоятельно.


Павиа   (12.03.13 13:41[14]

Я использую такой вот код
procedure Loop2D_3(var r:TBitMap; bm1,bm2:TBitMap; proc1:TProcLoop2d_1;proc2:TProcLoop2d_2); Overload;
var i,j,k,p:Integer;
LL,uf:Integer;
p1,p2,p3:PAByte;
begin
  LL:=DWord(bm1.ScanLine[1])-DWord(bm1.ScanLine[0]);
  LL:=LL-1;
  p1:=r.ScanLine[0];
  p2:=bm1.ScanLine[0];
  p3:=bm2.ScanLine[0];
  j:=bm1.Height;
  repeat
    Proc1(LL,p1,p2,p3);
    Inc(PByte(p1),LL);
    Inc(PByte(p2),LL);
    Inc(PByte(p3),LL);
    dec(j);
  until j=0;
end;


Накладные расходы этого кода составляют 1% точность измерения 0,001 или 0,1%.


XNA   (12.03.13 17:17[15]


> MBo ©   (12.03.13 08:19) [12]
>
> >GetScanline - неимоверно тяжелая функция!
> Она что, тратит время, сравнимое с обработкой строки?
>
> Вот библиотека попиксельного доступа:
> http://www.delphimaster.ru/articles/pixels/index.html
> Однако она на каждом шаге вычисляет адрес пикселов. При
> произвольных обращениях к разным местам картинки QPixels
> работает быстрее сканлайна. При последовательной обработке
> строк чуть быстрее сканлайн.


Попиксельно не надо.


> RWolf ©   (12.03.13 09:33) [13]
>
>
> > Как быть?
>
> не вызывать GetScanline, вычислять указатели самостоятельно.
>

Да, думаю сделать методы Lock(), Unlock.
Побыстрее будет.



> Павиа   (12.03.13 13:41) [14]
>
> Я использую такой вот код


А что это такое, не понял.
Что в цикле? Эффект?


Sapersky   (12.03.13 17:43[16]

Тут уже была по крайней мере одна мега-ветка про оптимизацию софтвера:
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1186325580&n=9
хотя, конечно, извлечь из неё что-то полезное непросто... в общем-то, и здесь основное уже сказали.


костыль   (15.11.13 11:18[17]

Считай на ГПУ, скорость в разы увеличится.


имя   (20.10.15 19:25[18]

Удалено модератором


Сергей   (29.11.16 18:13[19]

вообще по сокращению кода может ни чего не сделать, а вот по скорости можно. Если сократить количество циклов повторяющихся, если известно что количество циклов положительно, то разложить в цикле на два, если делится на 4, то разложить на 4 и т. д.


An a Student   (29.11.16 20:16[20]

Кто-то поднял древнюю тему, спам опять лезет? От себя по теме могу добавить следующее:


> Может ещё тормозить TBitmap, знаю внутри он не оптимален.


Враньё. Обычная API-обёртка над HDC/HBITMAP/DIB, да, совсем слегка кривоватая, но ни об "тормозить" или "не оптимален" речь не идёт.


> Bmp.Width - обращается к методу, что тормозит вложенный цикл.


Тоже, извините, враньё. Возможно так будет если использовать Делфи3 (и старее), или полностью принудительно отключить оптимизатор, не знаю... Но Делфи7 и Берлин такого не допускают, я смотрел асм-код.

И вообще обычно тормозят вовсе не циклы, а именно это "что-то делаем", сравните вот скорости ваших обработок и просто заливку одним цветом.

Кстати вычитал на одном другом форуме что вместо прыганий со Scanline можно просто работать через TPNGObject.Pixels[].


ЯЧтсия   (09.01.17 14:48[21]

Удалено модератором


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо