Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.11.22;
Скачать: CL | DM;

Вниз

Быстрое копирование битмапов   Найти похожие ветки 

 
antonn ©   (2008-01-12 18:04) [0]

Пересечение веток:
http://delphimaster.net/view/8-1192964708/
http://delphimaster.net/view/8-1192964708/

и теста  http://delphimaster.net/view/8-1192964708/

Собсно, есть код блитинга битмапов (TBitmap, 32bit), который почему то медленно выполняется на АМД (медленно относительно оппонентов от Интел, я понимаю, что может там мега процы начали делать, но не настолько же круто). Помогите дооптимизировать его :)


 
antonn ©   (2008-01-12 18:05) [1]

код:
procedure DrawBitmap_transcolor(BTSource,BTDest:TBitmap; _x,_y:integer; transcolor:TColor);
var SrcBits: pointer; DstBits: pointer;
   xTo, sx, YTo, ddx, ddy, sy, w, h, dstw, dsth: integer;
   inc1, inc2: integer;
   Sfscanline0,Dfscanline0,fbits:pointer;

   function DIBBits(BMP: TBitmap): Pointer;
   var Section:TDIBSECTION;
   begin
    BMP.HandleType:=bmDIB;
    GetObject(BMP.Handle,sizeof(TDIBSECTION),@Section);
    Result:=Section.dsBm.bmBits;
   end;
begin
 w:=BTSource.Width;  h:=BTSource.Height;
 dstw:=BTDest.Width;  dsth:=BTDest.Height;
 XTo:=_x+W-1; YTo:=_y+H-1;
 if(_y>=dstH)or(_x>=dstW)or(YTo<0)or(XTo<0) then exit;
 asm
   xor  eax, eax
   mov  ddx, eax
   mov  ddy, eax
 end;
 sx:=W;
 sy:=H;
 if _x<0 then begin
     ddx:=-_x;
     inc(sx,_x);
     _x:=0;
 end;
 if _y<0 then begin
     ddy:=-_y;
     inc(sy,_y);
     _y:=0;
 end;
 if XTo>=dstw then dec(sx,XTo-dstw+1);
 if YTo>=dsth then dec(sy,YTo-dsth+1);

 if (sx<=0)or(sy<=0) then exit;
     
 inc2:=-(((32*w+31) shr 3) and $FFFFFFFC);
 Sfscanline0:=pointer(integer(DIBBits(BTSource))+abs(inc2)*(h-1));
 SrcBits:=pointer(integer(Sfscanline0)+inc2*ddy+ddx*4);

 inc1:=-(((32*dstw+31) shr 3) and $FFFFFFFC);
 Dfscanline0:=pointer(integer(DIBBits(BTDest))+abs(inc1)*(dsth-1));
 DstBits:=pointer(integer(Dfscanline0)+inc1*_y+_x*4);

       asm
         push  ebx
         push  edi
         push  esi

         mov   ebx, TransColor
         and   ebx, $FFFFFF
       @outer_loop:
         mov   edi, DstBits
         mov   ecx, sx
         mov   esi, SrcBits
       @loop:
         mov   eax, [esi]
         mov   edx, [esi]
         and   eax, $FFFFFF
         add   esi, 4
         cmp   eax, ebx
         jz    @next
         mov   [edi], edx
       @next:
         add   edi, 4
         dec   ecx
         jnz   @loop
       @end:
         mov   ecx, inc1
         mov   eax, inc2
         add   DstBits, ecx
         add   SrcBits, eax

         dec   sy
         jnz   @outer_loop
         pop   esi
         pop   edi
         pop   ebx
      end;
end;


функция быстрого блитинга, затирает альфаканал.


 
antonn ©   (2008-01-12 18:07) [2]

ЗЫ понятно дело, что для операций в цикле вычисление адреса первой строки пикселов можно куда нибудь вынести. Но в циклах гонялись битмапы 1600*1200, основная нагрузка идет в асме.


 
Dib@zol ©   (2008-01-13 18:45) [3]

and   ebx, $FFFFFF
А нужно ли затирание верхнего байта там, где он не используется? Нафик ету строчку :)

mov   eax, [esi]
mov   edx, [esi]
Чтобы не "дёргать" память дважды, можно заменить последнюю строчку на  mov edx, eax. Правда, прирост производительности при этом мизерный, но етож всётки цикл :)

А вообще занятный алгоритм. Щас вот думаю, как повязать SrcBits и DstBits на EBP и ESP.


 
Sapersky   (2008-01-13 19:55) [4]

Можно попробовать CMOV. Но по моему опыту (на другом алгоритме), толку от неё чуть.
А если без спец. инструкций - то и asm необязателен, компилятор вполне справляется. Ну будет разница процентов 5, и то не факт, что в пользу "рукописного" варианта.


 
antonn [work)   (2008-01-13 21:53) [5]

мне на асме проще )


 
Kenny   (2008-01-13 22:36) [6]

Draw alpha with a: 2,8802308673309
Draw alpha: 1,64891236176665
Draw alpha MMX: 1,54101373219222
Draw transparent color: 1,17464649836781
Draw tr. color opacity MMX: 1,5966358852871
Draw rotate alpha: 5,10885266144161

---
Pentium M (1.73 Ghz, 533Mhz FSB, 2MB L2 cache)


 
OSokin   (2008-01-15 18:12) [7]

А если вот так?

        push  ebx
        push  edi
        push  esi

        mov   ebx, TransColor
        and   ebx, $FFFFFF
      @outer_loop:
        mov   edi, DstBits
        mov   ecx, sx
        mov   esi, SrcBits
      @loop:
        mov   eax, [esi]
        mov   edx, eax
        and   eax, $FFFFFF
        add   esi, 4
        xor   eax, ebx
        jz    @next
        mov   [edi], edx
      @next:
        add   edi, 4
        loop @loop
      @end:
        mov   ecx, inc1
        mov   eax, inc2
        add   DstBits, ecx
        add   SrcBits, eax

        dec   sy
        jnz   @outer_loop
        pop   esi
        pop   edi
        pop   ebx

Замена на луп дает выйгрыш в 1 байт =). Правда, не проверял, будет работать или нет, но твоя тестилка, модифицированная hiew"ом =), выдает такой результат:
Draw alpha with a: 7,32291837279389
Draw alpha: 5,28911366240431
Draw alpha MMX: 1,9601630027934
Draw transparent color: 0,899604913674843
Draw tr. color opacity MMX: 2,22137304124701
Draw rotate alpha: 9,56283062961568

До этого было так:
Draw alpha with a: 7,925456581538
Draw alpha: 5,84321204678404
Draw alpha MMX: 2,16867349828345
Draw transparent color: 0,993406174967481
Draw tr. color opacity MMX: 2,45866821997455
Draw rotate alpha: 10,6337005945738


 
antonn ©   (2008-01-15 18:28) [8]


> OSokin   (15.01.08 18:12) [7]

верни обратно dec   ecx и получишь еще медленней :)


 
OSokin   (2008-01-15 18:32) [9]

Тьфу, блин. Перепутал результаты =)


 
antonn ©   (2008-01-15 18:34) [10]

кстати) если вставить loop и убрать dec - ошибок нет, все выполняется) вот только блитится ровно половина (слева) битмапа, поэтому очень быстро:)


 
OSokin   (2008-01-15 20:04) [11]

о_О а разве loop @a не равен dec cx / jnz @a ???
А xor вместо cmp дает что-нибудь?



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

Текущий архив: 2009.11.22;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.013 c
15-1253630278
TRSteep
2009-09-22 18:37
2009.11.22
Авто дописывание кода


2-1254664097
bodun
2009-10-04 17:48
2009.11.22
Как правильно использовать указатели в данной задаче


2-1254932240
Johnnnnn
2009-10-07 20:17
2009.11.22
Сменить директорию диалога Open?


15-1252433478
GRAND
2009-09-08 22:11
2009.11.22
Курсы валют для прог (через FTP или что-то в этом роде)?


15-1253626742
StriderMan
2009-09-22 17:39
2009.11.22
рынок "тяжелых" вычислений