Форум: "Прочее";
Текущий архив: 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.046 c