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

Вниз

Можно ли как то оптимизировать данный участок кода   Найти похожие ветки 

 
DVM ©   (2007-05-09 14:36) [40]

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

Итак, было (510 fps):

for cy := 1 to ty do
 begin
   for cx := 1 to tx do
     begin
       inc(pmi^.blue, pc^.b);
       inc(pmi^.green, pc^.g);
       inc(pmi^.red, pc^.r);
       Inc(pc);
     end;
  inc(integer(pc), Delta);
end;


Стало (660 fps):


for cy := 1 to ty do
 begin
   b := 0; g := 0; r := 0;
   for CX := 1 to TX do
     begin
       inc(B, pc^.b);
       inc(g, pc^.g);
       inc(R, pc^.r);
       Inc(PC);
     end;
   mi.Blue := b; mi.Green := g; mi.Red := r;
   Inc(pmi.blue, mi.blue);
   Inc(pmi.green, mi.green);
   Inc(pmi.red, mi.red);
   inc(integer(pc), Delta);
 end;


Код стал странноват, но быстрее на 20 процентов.

Интересно, а еще быстрее можно?


 
oxffff ©   (2007-05-09 15:33) [41]


> Интересно, а еще быстрее можно?


Можно.

Software Optimization Guide for AMD Family 10h Processors
http://www.amd.com/us-en/assets/content_type/white_p…ch_docs/40546.pdf


 
Sapersky   (2007-05-09 22:43) [42]

А ведь все таки и твоя функция работает не совсем правильно, я сразу и не заметил.
Правильно работает, только если писать так:
procedure GetSum(var Src : PFColor; var Dst : PMatrixItem; Count : Integer);


Разумеется, указатель Src, если его передавать по значению (без var), после выполнения процедуры не инкрементируется. Ну а вручную инкрементировать трудно, что ли:
inc(integer(pc), Delta + tx * 3);
или вообще без указателей:
GetSum(@FDIB.Pixels24[cy, 1], @mi, tx);
т.к. во внешнем (вертикальном) цикле "ловить блох" не имеет смысла, да и TFastDIB.Pixels это не TBitmap.Pixels.

Интересно, а еще быстрее можно?

Можно всё-таки попробовать MMX... сейчас прикинул - получается 3 операции на пиксель вместо 6. Но для этого нужно:
1) Использовать 32-битные картинки вместо 24-битных. Или разложить 24 на 3 по 8, хотя это по многим причинам менее удобно.
2) Начало обрабатываемой области должно быть выравнено на 8 байт, т.е. на 2 пикселя, размер желательно тоже.
3) Обрабатывать за один вызов не более 65536 пикселей, т.к. размер счётчиков придётся сократить до word. Впрочем, это как раз не проблема.


 
DVM ©   (2007-05-09 23:01) [43]


> Разумеется, указатель Src, если его передавать по значению
> (без var), после выполнения процедуры не инкрементируется.
>

Да, я уже понял. Собственно меня вариант без использования доп процедуры даже больше устраивает.


> Можно всё-таки попробовать MMX...


> Использовать 32-битные картинки вместо 24-битных.

Не, отпадает - при конвертации/разложении потеряем весь прирост скорости.


 
Fenik ©   (2007-05-10 15:06) [44]

> DVM ©
> for cy := 1 to ty do
>  begin
>    b := 0; g := 0; r := 0;
>    for CX := 1 to TX do
>      begin
>        inc(B, pc^.b);
>        inc(g, pc^.g);
>        inc(R, pc^.r);
>        Inc(PC);
>      end;
>    mi.Blue := b; mi.Green := g; mi.Red := r;
>    Inc(pmi.blue, mi.blue);
>    Inc(pmi.green, mi.green);
>    Inc(pmi.red, mi.red);
>    inc(integer(pc), Delta);
>  end;

А что такое mi? Может проще:

   Inc(pmi.blue, b);
   Inc(pmi.green, g);
   Inc(pmi.red, r);

а то 3 лишних присваивания.


 
Fenik ©   (2007-05-10 15:06) [45]

> DVM ©
> for cy := 1 to ty do
>  begin
>    b := 0; g := 0; r := 0;
>    for CX := 1 to TX do
>      begin
>        inc(B, pc^.b);
>        inc(g, pc^.g);
>        inc(R, pc^.r);
>        Inc(PC);
>      end;
>    mi.Blue := b; mi.Green := g; mi.Red := r;
>    Inc(pmi.blue, mi.blue);
>    Inc(pmi.green, mi.green);
>    Inc(pmi.red, mi.red);
>    inc(integer(pc), Delta);
>  end;

А что такое mi? Может проще:

   Inc(pmi.blue, b);
   Inc(pmi.green, g);
   Inc(pmi.red, r);

а то 3 лишних присваивания.


 
DVM ©   (2007-05-10 15:18) [46]


> а то 3 лишних присваивания.

:) Они не лишние. Так вот быстрее чуть-чуть, как ни странно. К тому же они находятся во внешнем цикле - поэтому пофиг.


 
Knight ©   (2007-05-10 16:13) [47]

> [46] DVM ©   (10.05.07 15:18)

А если..

   b := pc^.b; g := pc^.g; r := pc^.r;
   for CX := 2 to TX do
     begin
       Inc(PC);
       inc(b, pc^.b);
       inc(g, pc^.g);
       inc(R, pc^.r);
     end;

Или что-то в этом направлении...


 
DVM ©   (2007-05-10 16:20) [48]


> Knight ©   (10.05.07 16:13) [47]

Все пляски вокруг внутреннего цикла почти лишены смысла. А так будет даже медленнее.


 
Knight ©   (2007-05-10 16:24) [49]

> [48] DVM ©   (10.05.07 16:20)

Разве три присваивания нулей и три inc-а быстрее чем просто присваивание первых элементов и переход сразу ко вторым?


 
Knight ©   (2007-05-10 16:41) [50]

[49] Да ещё помноженное на ty внешнего цикла...


 
Knight ©   (2007-05-10 16:57) [51]

А если несколько потоков запускать? %)


 
DVM ©   (2007-05-10 17:36) [52]


> А если несколько потоков запускать? %)

а мой код и так будет в нескольких потоках параллельно работать в реальной программе.


 
Sapersky   (2007-05-10 18:00) [53]

Ради интереса сделал-таки с MMX, только макс. кол-во обрабатываемых за вызов пикселей - 256, а не 65536, прочие условия см. [42]. Быстрее где-то в 1.2 раза.
Вот, может пригодится:

Type
 PMatrixItem16 = ^TMatrixItem16;
 TMatrixItem16 = record
   Blue, Green, Red, Alpha: Word;
 end;

procedure GetSumMMX(Src : PFColorA; Dst : PMatrixItem16; Count : Integer);
asm
 shr ecx, 1
 jz @exit

 db $0F,$EF,$D2           /// pxor mm2, mm2
 db $0F,$EF,$DB           /// pxor mm3, mm3
 db $0F,$EF,$E4           /// pxor mm4, mm4
@loop:
 db $0F,$6F,$00           /// movq mm0, [eax]
 db $0F,$6F,$C8           /// movq mm1, mm0
 db $0F,$60,$CA           /// punpcklbw mm1, mm2
 db $0F,$68,$C2           /// punpckhbw mm0, mm2
 db $0F,$FD,$D8           /// paddw mm3, mm0
 db $0F,$FD,$E1           /// paddw mm4, mm1
 add eax, 8
 dec ecx
jnz @loop
 db $0F,$FD,$DC           /// paddw mm3, mm4
 db $0F,$7F,$1A           /// movq [edx], mm3
@exit:
end;

После цикла с обработкой:
asm
 db $0F,$77               /// emms
end;


 
DVM ©   (2007-05-10 18:07) [54]


> Sapersky   (10.05.07 18:00) [53]

спасибо, погляжу



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

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

Наверх





Память: 0.55 MB
Время: 0.062 c
1-1176127944
SkySpeed
2007-04-09 18:12
2007.06.03
Как в режиме RunTime НОРМАЛЬНО изменить форму TForm?


2-1179306096
Forest
2007-05-16 13:01
2007.06.03
Несколько вопросов


2-1179156321
Ski1
2007-05-14 19:25
2007.06.03
как типу PAnsiChar присвоить тип String


1-1176196280
Jakudza
2007-04-10 13:11
2007.06.03
Проблема при закрытии формы MDI из DLL


2-1179137910
FIL-23
2007-05-14 14:18
2007.06.03
как подать звук на спикер из под XP





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский