Форум: "Прочее";
Текущий архив: 2014.05.18;
Скачать: [xml.tar.bz2];
ВнизБыстро закрасить кусок памяти Найти похожие ветки
← →
L8 (2013-11-13 19:22) [0]Имеется 32-битное изображение, его нужно быстро закрасить одним цветом.
Нашел такую функцию:
procedure FillDWORD(var Dest; Count, Value: LongInt); register;
asm
XCHG EDX, ECX
PUSH EDI
MOV EDI, EAX
MOV EAX, EDX
REP STOSD
POP EDI
end;
Использование:
FillDWORD(PByteArray(PtrImage)[0], Image.Width * Image.Height, $FF0000);
Вопрос, как сеё дело ускорить и нет ли в этом ассемблере, который я естественно не знаю, какая-нибудь брешь. Которая даст о себе знать при,
например, переносе программы на 64-бит.
← →
Inovet © (2013-11-13 19:37) [1]> [0] L8 (13.11.13 19:22)
> Которая даст о себе знать при,
> например, переносе программы на 64-бит.
Есть, не будет работать, там другой ассемблер.
← →
L8 (2013-11-13 19:41) [2]
> Inovet © (13.11.13 19:37) [1]
>
> > [0] L8 (13.11.13 19:22)
> > Которая даст о себе знать при,
> > например, переносе программы на 64-бит.
>
> Есть, не будет работать, там другой ассемблер.
>
Иногда пишут 4 * X, вместо SizeOf(DWORD) * X.
Не будет это работать.
← →
Павиа (2013-11-13 19:48) [3]
> Использование:FillDWORD(PByteArray(PtrImage)[0], Image.Width
> * Image.Height, $FF0000);
Тут цикл нужен.
> Имеется 32-битное изображение, его нужно быстро закрасить
> одним цветом.Нашел такую функцию:procedure FillDWORD(var
> Dest; Count, Value: LongInt); register;asm XCHG EDX, ECX
> PUSH EDI MOV EDI, EAX MOV EAX, EDX REP STOSD
> POP EDIend;
А смысл?? Обычно это не требуется. В любом случае взять готовую библиотеку.
← →
Rouse_ © (2013-11-13 19:49) [4]
> Вопрос, как сеё дело ускорить и нет ли в этом ассемблере,
> который я естественно не знаю, какая-нибудь брешь. Которая
> даст о себе знать при,
> например, переносе программы на 64-бит.
Ускорить можно и нужно, т.к. инструкция "REP STOSD" достаточно медлительная. Для 64 бит работать также будет (если убрать работу со стеком), но тже медленно.
Вот как-то так:procedure FillDWORD(var Dest; Count, Value: LongInt); register;
asm
XCHG EDX, ECX
// PUSH EDI
MOV EDI, EAX
MOV EAX, EDX
REP STOSD
// POP EDI
end;
ЗЫ: правда у меня дома только 32 бита и проверить не могу, но должно...
← →
Rouse_ © (2013-11-13 19:57) [5]ЗЫ: В общем случае, стандартный FillChar реализованный в Delhi 2005 и выше (с реализацией через FPU) будет пошустрее этого кода.
← →
брат Птибурдукова (2013-11-13 20:00) [6]
> // PUSH EDI
An asm statement must preserve the EDI, ESI, ESP, EBP, and EBX registers, but can freely modify the EAX, ECX, and EDX registers
> инструкция "REP STOSD" достаточно медлительная
А что вместо? MMX? Для 8086 как раз REP STOSx рекомендовали использовать. Некоторые источники даже намекали, что при этом перепрограммируется КПДП, и данные идут через него :о)
← →
Rouse_ © (2013-11-13 20:11) [7]
> An asm statement must preserve the EDI, ESI, ESP, EBP, and
> EBX registers,
Ну это я показал чтобы скомпилялась под 64
> А что вместо?
Ручками MOV + JNE
← →
Rouse_ © (2013-11-13 20:12) [8]
> Ручками MOV + JNE
ЗЫ: + FPU конечно.
← →
jack128_ (2013-11-13 20:43) [9]
> ЗЫ: В общем случае, стандартный FillChar реализованный в
> Delhi 2005 и выше (с реализацией через FPU) будет пошустрее
> этого кода.
жаль только FillChar не решает задачу топикстартера ;-)
← →
все арамисы, а я Дартаньян (2013-11-13 20:56) [10]
> Rouse_ © (13.11.13 20:11) [7]
MOV быстрее STOS? о_О
← →
Dimka Maslov © (2013-11-13 20:56) [11]Давным давно я проводил тесты и у меня получалось, что REP STOSx получалось медленнее, чем цикл с MOV [eax+ecx], xx и LOOP
← →
Павиа (2013-11-13 21:01) [12]
> > инструкция "REP STOSD" достаточно медлительнаяА что
> вместо? MMX? Для 8086 как раз REP STOSx рекомендовали использовать.
> Некоторые источники даже намекали, что при этом перепрограммируется
> КПДП, и данные идут через него :о)
Для i7 тоже STOSD вместо MOV.
Правда SIMD будет быстрее любого их этого.
+ FPU конечно.
А что мелочиться тогда уж GPU. Или ПЛИС.
← →
Павиа (2013-11-13 21:04) [13]
> MOV быстрее STOS? о_О
Быстрее только надо знать на каком процессоре.
← →
Rouse_ © (2013-11-13 21:17) [14]
> jack128_ (13.11.13 20:43) [9]
> жаль только FillChar не решает задачу топикстартера ;-)
Лолшто?
> все арамисы, а я Дартаньян (13.11.13 20:56) [10]
> MOV быстрее STOS? о_О
По тактам монопенисюально, кабы не цикл через REP
> Dimka Maslov © (13.11.13 20:56) [11]
> Давным давно я проводил тесты и у меня получалось, что REP
> STOSx получалось медленнее, чем цикл с MOV [eax+ecx], xx
> и LOOP
LOOP - тоже одна из причин задержек (минус такт) Jxx в данном случае выгодней.
> А что мелочиться тогда уж GPU. Или ПЛИС.
А я не мелочусь, я говорю как есть. Да ну на GPU для такой задачи также будет просадка (зачем гонять буфера для такой тривиальной задачи)?
← →
Rouse_ © (2013-11-13 21:22) [15]ЗЫ: на данный момент самый оптимальный вариант (используемый кстати в составе Delphi выглядит в реализации от John O"Harrow).
procedure _FillChar(var Dest; Count: NativeInt; Value: _AnsiChr);
asm // Size = 153 Bytes
CMP EDX, 32
MOV CH, CL // Copy Value into both Bytes of CX
JL @@Small
MOV [EAX ], CX // Fill First 8 Bytes
MOV [EAX+2], CX
MOV [EAX+4], CX
MOV [EAX+6], CX
SUB EDX, 16
FLD QWORD PTR [EAX]
FST QWORD PTR [EAX+EDX] // Fill Last 16 Bytes
FST QWORD PTR [EAX+EDX+8]
MOV ECX, EAX
AND ECX, 7 // 8-Byte Align Writes
SUB ECX, 8
SUB EAX, ECX
ADD EDX, ECX
ADD EAX, EDX
NEG EDX
@@Loop:
FST QWORD PTR [EAX+EDX] // Fill 16 Bytes per Loop
FST QWORD PTR [EAX+EDX+8]
ADD EDX, 16
JL @@Loop
FFREE ST(0)
FINCSTP
RET
NOP
NOP
NOP
@@Small:
TEST EDX, EDX
JLE @@Done
MOV [EAX+EDX-1], CL // Fill Last Byte
AND EDX, -2 // No. of Words to Fill
NEG EDX
{$IFDEF PIC}
PUSH EAX
PUSH EBX
PUSH ECX
CALL GetGOT
ADD EAX, offset @@SmallFill + 60
LEA EDX, [EAX + EDX * 2]
POP ECX
POP EBX
POP EAX
{$ELSE !PIC}
LEA EDX, [@@SmallFill + 60 + EDX * 2]
{$ENDIF !PIC}
JMP EDX
{$IFNDEF PIC}
NOP // Align Jump Destinations
NOP
{$ENDIF !PIC}
@@SmallFill:
MOV [EAX+28], CX
MOV [EAX+26], CX
MOV [EAX+24], CX
MOV [EAX+22], CX
MOV [EAX+20], CX
MOV [EAX+18], CX
MOV [EAX+16], CX
MOV [EAX+14], CX
MOV [EAX+12], CX
MOV [EAX+10], CX
MOV [EAX+ 8], CX
MOV [EAX+ 6], CX
MOV [EAX+ 4], CX
MOV [EAX+ 2], CX
MOV [EAX ], CX
RET // DO NOT REMOVE - This is for Alignment
@@Done:
end;
Достаточно красиво и оптимально без использования как LOOP так и REP STOSx
← →
Sapersky (2013-11-13 21:22) [16]FillChar заполняет байтами, а нужно DWord (цвет). Хотя это почти то же самое, и при желании можно допилить какой-нибудь вариант FillChar из FastCode:
http://www.fastcode.dk/fastcodeproject/fastcodeproject/25.htm
← →
Rouse_ © (2013-11-13 21:23) [17]Особливо красиво выглядит концовка ввиде:
LEA EDX, [@@SmallFill + 60 + EDX * 2]
JMP EDX
← →
Rouse_ © (2013-11-13 21:24) [18]
> Sapersky (13.11.13 21:22) [16]
> FillChar заполняет байтами, а нужно DWord (цвет).
Она заполняет по 16 байт + концовка...
← →
antonn © (2013-11-13 21:24) [19]
> Иногда пишут 4 * X, вместо SizeOf(DWORD) * X.
> Не будет это работать.
dword же всегда 4 байта?
← →
Sapersky (2013-11-13 21:28) [20]Роуз, алё, проснись. У цвета значения RGBA могут быть разные, а FillChar заполняет всё одним байтом. Хотя, если нужно очищать чёрным или белым, то сойдёт и FillChar.
← →
Rouse_ © (2013-11-13 21:31) [21]
> Sapersky (13.11.13 21:28) [20]
> Роуз, алё, проснись. У цвета значения RGBA могут быть разные,
> а FillChar заполняет всё одним байтом. Хотя, если нужно
> очищать чёрным или белым, то сойдёт и FillChar.
Ыц...
Воть это я лажанулся :)
Пардон - был не прав :)))
← →
все арамисы, а я Дартаньян (2013-11-13 21:40) [22]
> или белым
…то 255 в старшем байте может дать забавные эффекты, не?
← →
Inovet © (2013-11-13 22:04) [23]> [14] Rouse_ © (13.11.13 21:17)
> LOOP - тоже одна из причин задержек (минус такт) Jxx в данном
> случае выгодней.
REP ещё понимаю, а LOOP зачем они выпиливают. Так и не собрался с этим разобраться.
← →
Rouse_ © (2013-11-13 22:13) [24]
> а LOOP зачем они выпиливают. Так и не собрался с этим разобраться.
Три такта против двух.
← →
Inovet © (2013-11-13 22:16) [25]> [24] Rouse_ © (13.11.13 22:13)
> Три такта против двух.
Так я про интеловцев. Что их вынудило сделать 3 такта. Казалось бы, должно быть наоборот.
← →
Sapersky (2013-11-13 22:45) [26]
> …то 255 в старшем байте может дать забавные эффекты, не?
Это по-моему фишка исключительно VCL - воспринимать TColor с битом в старшем разряде как системный цвет, т.е. индекс в системной палитре. И я сомневаюсь, что это относится к содержимому битмапов (хотя бы из соображений производительности - для каждого пикселя дёргать GetSysColor накладно).
А при самостоятельной обработке можно использовать 4-й байт как угодно. Если это альфа-канал, то всё логично - будет полная непрозрачность.
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2014.05.18;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.003 c