real_het

FastCountBits.dpr

Oct 1st, 2011
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 6.04 KB | None | 0 0
  1. program FastCountBits;
  2.  
  3. {$APPTYPE CONSOLE}
  4.  
  5. uses
  6.   SysUtils, het.Utils, het.FileSys;
  7.  
  8. function CountBits_Cyclic_B(value:byte):integer;
  9. begin
  10.   result:=0;
  11.   while value<>0 do begin
  12.     inc(result);
  13.     value:=value and (value-1);
  14.   end;
  15. end;
  16.  
  17. function CountBits_Cyclic(var Data;const Len:integer):integer;var P,PEnd:PByte;
  18. begin
  19.   result:=0;if Len<=0 then exit;
  20.   P:=@Data;PEnd:=PSucc(P,Len);while P<>PEnd do begin
  21.     inc(result,CountBits_Cyclic_B(P^));inc(P);end;
  22. end;
  23.  
  24. function _CountBits_Arith_B(const value:byte):integer;
  25. begin
  26.   result:=value  and $55+value  shr 1 and $55;
  27.   result:=result and $33+result shr 2 and $33;
  28.   result:=result and  $F+result shr 4;
  29. end;
  30.  
  31. function _CountBits_Arith_W(const value:word):integer;
  32. begin
  33.   result:=value  and $5555+value  shr 1 and $5555;
  34.   result:=result and $3333+result shr 2 and $3333;
  35.   result:=result and $0F0F+result shr 4 and $0F0F;
  36.   result:=result and $00FF+result shr 8;
  37. end;
  38.  
  39. function _CountBits_Arith_DW(const value:cardinal):integer;
  40. begin
  41.   result:=value  and $55555555+value  shr 1 and $55555555;
  42.   result:=result and $33333333+result shr 2 and $33333333;
  43.   result:=result and $0F0F0F0F+result shr 4 and $0F0F0F0F;
  44.   result:=result and $00FF00FF+result shr 8 and $00FF00FF;
  45.   result:=result and $FFFF    +result shr 16;
  46. end;
  47.  
  48. function CountBits_Arith(var Data;const Len:integer):integer;var P,PEnd:PByte;
  49. begin
  50.   result:=0;if Len<=0 then exit;
  51.   P:=@Data;PEnd:=PSucc(P,Len);while P<>PEnd do begin
  52.     inc(result,_CountBits_Arith_B(P^));inc(P);end;
  53. end;
  54.  
  55. function CountBits_Arith_W(var Data;const Len:integer):integer;var P,PEnd:PWord;
  56. begin
  57.   result:=0;if Len<=0 then exit;
  58.   P:=@Data;PEnd:=PSucc(P,Len);while P<>PEnd do begin
  59.     inc(result,_CountBits_Arith_W(P^));inc(P);end;
  60. end;
  61.  
  62. function CountBits_Arith_DW(var Data;const Len:integer):integer;var P,PEnd:PCardinal;
  63. begin
  64.   result:=0;if Len<=0 then exit;
  65.   P:=@Data;PEnd:=PSucc(P,Len);while P<>PEnd do begin
  66.     inc(result,_CountBits_Arith_DW(P^));inc(P);end;
  67. end;
  68.  
  69. var lookup:array[0..$FF]of byte;
  70.  
  71. function CountBits_Lookup(var Data;const Len:integer):integer;var P,PEnd:PByte;
  72. begin
  73.   result:=0;if Len<=0 then exit;
  74.   P:=@Data;PEnd:=PSucc(P,Len);while P<>PEnd do begin
  75.     inc(result,Lookup[P^]);inc(P);end;
  76. end;
  77.  
  78. var lookupW:array[0..$FFFF]of byte;
  79.  
  80. function CountBits_Lookup_W(var Data;const Len:integer):integer;var P,PEnd:PWord;
  81. begin
  82.   result:=0;if Len<=0 then exit;
  83.   P:=@Data;PEnd:=PSucc(P,Len);while P<>PEnd do begin
  84.     inc(result,LookupW[P^]);inc(P);end;
  85. end;
  86.  
  87. function _CountBits_SSE_Aligned(P,PEnd:pointer):integer;
  88. const countfetch=30;
  89. asm
  90.   push esi;  xor esi,esi //counter
  91.  
  92.   mov ecx,$55555555 movd xmm4,ecx pshufd xmm4,xmm4,0
  93.   mov ecx,$33333333 movd xmm5,ecx pshufd xmm5,xmm5,0
  94.   mov ecx,$0F0F0F0F movd xmm6,ecx pshufd xmm6,xmm6,0
  95.  
  96.   @@1:
  97.     lea ecx,[eax+$10*countfetch]
  98.     cmp ecx,edx
  99.     cmova ecx,edx //ecx:next segment end
  100.  
  101.     cmp eax,ecx jae @@3//exit
  102.  
  103.     pxor xmm7,xmm7//byte sum
  104.     @@2:
  105.       movdqa xmm0,[eax]                  movdqa xmm2,[eax+$10]
  106.  
  107.                        movdqa xmm1,xmm0                   movdqa xmm3,xmm2
  108.       pand xmm0,xmm4   psrld  xmm1,1     pand xmm2,xmm4   psrld  xmm3,1
  109.                        pand xmm1,xmm4                     pand xmm3,xmm4
  110.       paddb xmm0,xmm1                    paddb xmm2,xmm3
  111.  
  112.                        movdqa xmm1,xmm0                   movdqa xmm3,xmm2
  113.       pand xmm0,xmm5   psrld  xmm1,2     pand xmm2,xmm5   psrld  xmm3,2
  114.                        pand xmm1,xmm5                     pand xmm3,xmm5
  115.       paddb xmm0,xmm1                    paddb xmm2,xmm3                 prefetchnta [eax+$100]
  116.                                                                          add eax,$20
  117.                        movdqa xmm1,xmm0                   movdqa xmm3,xmm2
  118.       pand xmm0,xmm6   psrld  xmm1,4     pand xmm2,xmm6   psrld  xmm3,4
  119.                        pand xmm1,xmm6                     pand xmm3,xmm6
  120.       paddb xmm0,xmm1                    paddb xmm2,xmm3
  121.  
  122.       paddb xmm7,xmm0                    paddb xmm7,xmm2
  123.  
  124.     cmp eax,ecx jb @@2
  125.  
  126.     movdqa xmm0,xmm7  pslld xmm0,24  psrld xmm0,24
  127.     movdqa xmm1,xmm7  pslld xmm1,16  psrld xmm1,24  paddd xmm0,xmm1
  128.     movdqa xmm1,xmm7  pslld xmm1, 8  psrld xmm1,24  paddd xmm0,xmm1
  129.     movdqa xmm1,xmm7  pslld xmm1, 0  psrld xmm1,24  paddd xmm0,xmm1
  130.  
  131.     pshufd xmm1,xmm0,2+3 shl 2
  132.     paddd xmm0,xmm1
  133.     pshufd xmm1,xmm0,1
  134.     paddd xmm0,xmm1
  135.     movd ecx,xmm0
  136.     add esi,ecx
  137.  
  138.   jmp @@1
  139.   @@3:
  140.  
  141.   mov eax,esi
  142.   pop esi
  143. end;
  144.  
  145. function CountBits_SSE(var Data;const Len:integer):integer;var P,PEnd,PSSEEnd:PByte;
  146. begin
  147.   result:=0;if Len<=0 then exit;
  148.   P:=@Data;PEnd:=PSucc(P,Len);while(P<>PEnd)and(cardinal(P)and $F<>0)do begin
  149.     inc(result,_CountBits_Arith_B(P^));inc(P);end;
  150.  
  151.   PSSEEnd:=pAlignDown(pEnd,$20);
  152.   if cardinal(PSSEEnd)>cardinal(P)then begin
  153.     inc(result,_CountBits_SSE_Aligned(P,PSSEEnd));
  154.     P:=PSSEEnd;
  155.   end;
  156.  
  157.   while(P<>PEnd)do begin
  158.     inc(result,_CountBits_Arith_B(P^));inc(P);end;
  159. end;
  160.  
  161. type
  162.   TCountBits=function(var Data;const Len:integer):integer;
  163.  
  164. procedure Test(name:string;proc:TCountBits);
  165. var Data:AnsiString;
  166.     res,i:integer;
  167. begin
  168.   Data:=FileReadStr('c:\opticalillusion.bmp');
  169.   for i:=0 to 0 do begin
  170.     perfStart(name);
  171.     res:=proc(Data[1],length(Data)and -4);
  172.     Writeln(perfReport+' res='+tostr(res));
  173.   end;
  174. end;
  175.  
  176. var i:integer;
  177. begin
  178.   try
  179.     for i:=0 to high(lookup)do lookup[i]:=CountBits_Cyclic_B(i);
  180.     for i:=0 to high(lookupw)do lookupw[i]:=CountBits_Cyclic(i,2);
  181.  
  182.     for i:=0 to 3 do begin
  183.       writeln('-------- round#'+tostr(i));
  184.       Test('byte, ciklusos ',@CountBits_Cyclic);
  185.       Test('byte, szamolos ',@CountBits_Arith);
  186.       Test('byte, lookup   ',@CountBits_Lookup);
  187.       Test('word, szamolos ',@CountBits_Arith_W);
  188.       Test('word, lookup   ',@CountBits_Lookup_W);
  189.       Test('dword, szamolos',@CountBits_Arith_DW);
  190.       Test('sse, szamolos  ',@CountBits_SSE);
  191.     end;
  192.     readln;
  193.   except
  194.     on E: Exception do
  195.       Writeln(E.ClassName, ': ', E.Message);
  196.   end;
  197. end.
Advertisement
Add Comment
Please, Sign In to add comment