real_het

TestFastMove.dpr

Sep 18th, 2011
251
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 22.43 KB | None | 0 0
  1. program TestFastMove;
  2. {$APPTYPE CONSOLE}
  3. uses Windows, SysUtils;
  4.  
  5. ////////////////////////////////////////////////////////////////////////////////
  6. ///  FastMove                                                  real_het 2011 ///
  7. ////////////////////////////////////////////////////////////////////////////////
  8.  
  9. {$R-}{$O+}
  10.  
  11. var
  12.   FastMoveCacheLimit:integer=3 shl 20; //should set to half of the cache size of one processor core
  13.  
  14. procedure FastMove(const src;var dst;size:integer);
  15.  
  16.   procedure _SSE_Move64_fwd_nocache(dst,dstEnd:pointer;dstToSrc:integer);
  17.   asm
  18.   @@1:
  19.     movups xmm0,[eax+ecx+$00]
  20.     movups xmm1,[eax+ecx+$10]
  21.     movups xmm2,[eax+ecx+$20]
  22.     movups xmm3,[eax+ecx+$30]
  23.     movntps [eax+$00],xmm0 prefetchnta [eax+ecx+$100]
  24.     movntps [eax+$10],xmm1 add eax,$40
  25.     movntps [eax+$20-$40],xmm2
  26.     movntps [eax+$30-$40],xmm3 cmp eax,edx jne @@1
  27.   end;
  28.  
  29.   procedure _SSE_Move64_fwd_cache(dst,dstEnd:pointer;dstToSrc:integer);
  30.  
  31.     procedure A1;const a=1;//reference implementation
  32.     asm
  33.       movdqa xmm0,[eax+ecx+$00]
  34.     @@1:
  35.       movdqa xmm1,[eax+ecx+$10]
  36.       movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a
  37.       movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a
  38.       movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a
  39.       movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a
  40.       movdqa [eax+$10    ],xmm2  add eax,$40
  41.       movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100]
  42.       movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1
  43.     end;
  44.  
  45.     //copy+paste
  46.     procedure A2;const a=$2;asm movdqa xmm0,[eax+ecx+$00];@@1:;movdqa xmm1,[eax+ecx+$10];movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a;movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a;movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a;movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a;movdqa [eax+$10    ],xmm2  add eax,$40;movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100];movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1 ret;end;
  47.     procedure A3;const a=$3;asm movdqa xmm0,[eax+ecx+$00];@@1:;movdqa xmm1,[eax+ecx+$10];movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a;movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a;movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a;movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a;movdqa [eax+$10    ],xmm2  add eax,$40;movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100];movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1 ret;end;
  48.     procedure A4;const a=$4;asm movdqa xmm0,[eax+ecx+$00];@@1:;movdqa xmm1,[eax+ecx+$10];movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a;movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a;movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a;movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a;movdqa [eax+$10    ],xmm2  add eax,$40;movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100];movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1 ret;end;
  49.     procedure A5;const a=$5;asm movdqa xmm0,[eax+ecx+$00];@@1:;movdqa xmm1,[eax+ecx+$10];movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a;movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a;movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a;movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a;movdqa [eax+$10    ],xmm2  add eax,$40;movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100];movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1 ret;end;
  50.     procedure A6;const a=$6;asm movdqa xmm0,[eax+ecx+$00];@@1:;movdqa xmm1,[eax+ecx+$10];movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a;movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a;movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a;movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a;movdqa [eax+$10    ],xmm2  add eax,$40;movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100];movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1 ret;end;
  51.     procedure A7;const a=$7;asm movdqa xmm0,[eax+ecx+$00];@@1:;movdqa xmm1,[eax+ecx+$10];movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a;movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a;movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a;movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a;movdqa [eax+$10    ],xmm2  add eax,$40;movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100];movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1 ret;end;
  52.     procedure A8;const a=$8;asm movdqa xmm0,[eax+ecx+$00];@@1:;movdqa xmm1,[eax+ecx+$10];movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a;movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a;movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a;movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a;movdqa [eax+$10    ],xmm2  add eax,$40;movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100];movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1 ret;end;
  53.     procedure A9;const a=$9;asm movdqa xmm0,[eax+ecx+$00];@@1:;movdqa xmm1,[eax+ecx+$10];movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a;movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a;movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a;movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a;movdqa [eax+$10    ],xmm2  add eax,$40;movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100];movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1 ret;end;
  54.     procedure AA;const a=$A;asm movdqa xmm0,[eax+ecx+$00];@@1:;movdqa xmm1,[eax+ecx+$10];movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a;movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a;movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a;movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a;movdqa [eax+$10    ],xmm2  add eax,$40;movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100];movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1 ret;end;
  55.     procedure AB;const a=$B;asm movdqa xmm0,[eax+ecx+$00];@@1:;movdqa xmm1,[eax+ecx+$10];movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a;movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a;movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a;movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a;movdqa [eax+$10    ],xmm2  add eax,$40;movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100];movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1 ret;end;
  56.     procedure AC;const a=$C;asm movdqa xmm0,[eax+ecx+$00];@@1:;movdqa xmm1,[eax+ecx+$10];movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a;movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a;movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a;movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a;movdqa [eax+$10    ],xmm2  add eax,$40;movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100];movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1 ret;end;
  57.     procedure AD;const a=$D;asm movdqa xmm0,[eax+ecx+$00];@@1:;movdqa xmm1,[eax+ecx+$10];movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a;movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a;movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a;movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a;movdqa [eax+$10    ],xmm2  add eax,$40;movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100];movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1 ret;end;
  58.     procedure AE;const a=$E;asm movdqa xmm0,[eax+ecx+$00];@@1:;movdqa xmm1,[eax+ecx+$10];movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a;movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a;movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a;movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a;movdqa [eax+$10    ],xmm2  add eax,$40;movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100];movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1 ret;end;
  59.     procedure AF;const a=$F;asm movdqa xmm0,[eax+ecx+$00];@@1:;movdqa xmm1,[eax+ecx+$10];movdqa xmm2,[eax+ecx+$20]  movdqa xmm7,xmm1  palignr xmm1,xmm0,a;movdqa xmm3,[eax+ecx+$30]  movdqa xmm6,xmm2  palignr xmm2,xmm7,a;movdqa xmm4,[eax+ecx+$40]  movdqa xmm5,xmm3  palignr xmm3,xmm6,a;movdqa [eax+$00    ],xmm1  movdqa xmm0,xmm4  palignr xmm4,xmm5,a;movdqa [eax+$10    ],xmm2  add eax,$40;movdqa [eax+$20-$40],xmm3  prefetchnta [eax+ecx+$100];movdqa [eax+$30-$40],xmm4  cmp eax,edx jne @@1 ret;end;
  60.  
  61.   asm
  62.     test ecx,$F jz @@2
  63.     push esi
  64.     mov esi,ecx; and esi,$f; lea esi,[esi*4+offset @@jt-4]; //select function
  65.     and ecx,not $f //align delta
  66.     call [esi]
  67.     pop esi
  68.     ret
  69.     @@jt: dd A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF
  70.   @@2:
  71.     movaps xmm0,[eax+ecx+$00]
  72.     movaps xmm1,[eax+ecx+$10]
  73.     movaps xmm2,[eax+ecx+$20]
  74.     movaps xmm3,[eax+ecx+$30]
  75.     movaps [eax+$00],xmm0 prefetchnta [eax+ecx+$100]
  76.     movaps [eax+$10],xmm1 add eax,$40
  77.     movaps [eax+$20-$40],xmm2
  78.     movaps [eax+$30-$40],xmm3 cmp eax,edx jne @@2
  79.   end;
  80.  
  81.   procedure _SSE_Move64_rev_nocache(dst,dstEnd:pointer;dstToSrc:integer);
  82.   asm
  83.     xchg edx,eax sub eax,$40 sub edx,$40 //mirror buffer start/end positions
  84.   @@1:
  85.     movups xmm0,[eax+ecx+$00]
  86.     movups xmm1,[eax+ecx+$10]
  87.     movups xmm2,[eax+ecx+$20]
  88.     movups xmm3,[eax+ecx+$30]
  89.     movntps [eax+$00],xmm0 prefetchnta [eax+ecx-$100]
  90.     movntps [eax+$10],xmm1 sub eax,$40
  91.     movntps [eax+$20+$40],xmm2
  92.     movntps [eax+$30+$40],xmm3 cmp eax,edx jne @@1
  93.   end;
  94.  
  95.   procedure _SSE_Move64_rev_cache(dst,dstEnd:pointer;dstToSrc:integer);
  96.  
  97.     procedure A1;const a=1;//reference implementation
  98.     asm
  99.       movdqa xmm0,[eax+ecx+$30]
  100.     @@1:
  101.       movdqa xmm1,[eax+ecx+$20]
  102.       movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a
  103.       movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a
  104.       movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a
  105.       movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4
  106.       movdqa [eax+$20    ],xmm1  sub eax,$40
  107.       movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100]
  108.       movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret
  109.     end;
  110.  
  111.     //copy+paste
  112.     procedure A2;const a=$2;asm movdqa xmm0,[eax+ecx+$30];@@1:;  movdqa xmm1,[eax+ecx+$20];  movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a;  movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a;  movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a;  movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4;  movdqa [eax+$20    ],xmm1  sub eax,$40;  movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100];  movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret;  end;
  113.     procedure A3;const a=$3;asm movdqa xmm0,[eax+ecx+$30];@@1:;  movdqa xmm1,[eax+ecx+$20];  movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a;  movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a;  movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a;  movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4;  movdqa [eax+$20    ],xmm1  sub eax,$40;  movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100];  movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret;  end;
  114.     procedure A4;const a=$4;asm movdqa xmm0,[eax+ecx+$30];@@1:;  movdqa xmm1,[eax+ecx+$20];  movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a;  movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a;  movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a;  movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4;  movdqa [eax+$20    ],xmm1  sub eax,$40;  movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100];  movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret;  end;
  115.     procedure A5;const a=$5;asm movdqa xmm0,[eax+ecx+$30];@@1:;  movdqa xmm1,[eax+ecx+$20];  movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a;  movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a;  movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a;  movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4;  movdqa [eax+$20    ],xmm1  sub eax,$40;  movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100];  movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret;  end;
  116.     procedure A6;const a=$6;asm movdqa xmm0,[eax+ecx+$30];@@1:;  movdqa xmm1,[eax+ecx+$20];  movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a;  movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a;  movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a;  movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4;  movdqa [eax+$20    ],xmm1  sub eax,$40;  movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100];  movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret;  end;
  117.     procedure A7;const a=$7;asm movdqa xmm0,[eax+ecx+$30];@@1:;  movdqa xmm1,[eax+ecx+$20];  movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a;  movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a;  movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a;  movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4;  movdqa [eax+$20    ],xmm1  sub eax,$40;  movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100];  movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret;  end;
  118.     procedure A8;const a=$8;asm movdqa xmm0,[eax+ecx+$30];@@1:;  movdqa xmm1,[eax+ecx+$20];  movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a;  movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a;  movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a;  movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4;  movdqa [eax+$20    ],xmm1  sub eax,$40;  movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100];  movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret;  end;
  119.     procedure A9;const a=$9;asm movdqa xmm0,[eax+ecx+$30];@@1:;  movdqa xmm1,[eax+ecx+$20];  movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a;  movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a;  movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a;  movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4;  movdqa [eax+$20    ],xmm1  sub eax,$40;  movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100];  movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret;  end;
  120.     procedure AA;const a=$A;asm movdqa xmm0,[eax+ecx+$30];@@1:;  movdqa xmm1,[eax+ecx+$20];  movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a;  movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a;  movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a;  movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4;  movdqa [eax+$20    ],xmm1  sub eax,$40;  movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100];  movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret;  end;
  121.     procedure AB;const a=$B;asm movdqa xmm0,[eax+ecx+$30];@@1:;  movdqa xmm1,[eax+ecx+$20];  movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a;  movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a;  movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a;  movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4;  movdqa [eax+$20    ],xmm1  sub eax,$40;  movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100];  movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret;  end;
  122.     procedure AC;const a=$C;asm movdqa xmm0,[eax+ecx+$30];@@1:;  movdqa xmm1,[eax+ecx+$20];  movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a;  movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a;  movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a;  movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4;  movdqa [eax+$20    ],xmm1  sub eax,$40;  movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100];  movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret;  end;
  123.     procedure AD;const a=$D;asm movdqa xmm0,[eax+ecx+$30];@@1:;  movdqa xmm1,[eax+ecx+$20];  movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a;  movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a;  movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a;  movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4;  movdqa [eax+$20    ],xmm1  sub eax,$40;  movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100];  movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret;  end;
  124.     procedure AE;const a=$E;asm movdqa xmm0,[eax+ecx+$30];@@1:;  movdqa xmm1,[eax+ecx+$20];  movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a;  movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a;  movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a;  movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4;  movdqa [eax+$20    ],xmm1  sub eax,$40;  movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100];  movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret;  end;
  125.     procedure AF;const a=$F;asm movdqa xmm0,[eax+ecx+$30];@@1:;  movdqa xmm1,[eax+ecx+$20];  movdqa xmm2,[eax+ecx+$10]  palignr xmm0,xmm1,a;  movdqa xmm3,[eax+ecx+$00]  palignr xmm1,xmm2,a;  movdqa xmm4,[eax+ecx-$10]  palignr xmm2,xmm3,a;  movdqa [eax+$30    ],xmm0  palignr xmm3,xmm4,a  movdqa xmm0,xmm4;  movdqa [eax+$20    ],xmm1  sub eax,$40;  movdqa [eax+$10+$40],xmm2  prefetchnta [eax+ecx-$100];  movdqa [eax+$00+$40],xmm3  cmp eax,edx jne @@1 ret;  end;
  126.  
  127.   asm
  128.     xchg edx,eax sub eax,$40 sub edx,$40 //mirror buffer start/end positions
  129.     test ecx,$F jz @@2 //aligned?
  130.     push esi
  131.     mov esi,ecx; and esi,$f; lea esi,[esi*4+offset @@jt-4]; //select function
  132.     and ecx,not $f; add ecx,$10 //align delta
  133.     call [esi]
  134.     pop esi
  135.     ret
  136.     @@jt: dd A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF
  137.   @@2:
  138.     movaps xmm0,[eax+ecx+$00]
  139.     movaps xmm1,[eax+ecx+$10]
  140.     movaps xmm2,[eax+ecx+$20]
  141.     movaps xmm3,[eax+ecx+$30]
  142.     movaps [eax+$00],xmm0 prefetchnta [eax+ecx-$100]
  143.     movaps [eax+$10],xmm1 sub eax,$40
  144.     movaps [eax+$20+$40],xmm2
  145.     movaps [eax+$30+$40],xmm3 cmp eax,edx jne @@2
  146.   end;
  147.  
  148. const AlignPosMask=16-1;
  149.       AlignSizeMask=64-1;
  150.  
  151. var delta:integer;
  152.     pDst,pDstInner,pDstEnd,pDstInnerEnd:integer;
  153.     InnerSize:integer;
  154.     reverse,nocache,unaligned:boolean;
  155. begin
  156.   if size<(AlignSizeMask+1)*2 then begin system.Move(src,dst,size);exit end;
  157.   //check params
  158.   if(@src=nil)or(@dst=nil)then exit;
  159.   delta:=integer(@dst)-integer(@src);
  160.   if delta=0 then exit;
  161.   reverse:=(delta>0)and(delta<size);
  162.   delta:=-delta;//Delta: points from dst -> src
  163.   unaligned:=(delta and $f)<>0;
  164.  
  165.   pDst:=integer(@dst);
  166.   pDstEnd:=pDst+size;
  167.   pDstInner:=(pDst+AlignPosMask+16*ord(    reverse and unaligned))and not AlignPosMask;
  168.   InnerSize:=(pDstEnd-pDstInner-16*ord(not reverse and unaligned))and not AlignSizeMask;
  169.   pDstInnerEnd:=pDstInner+InnerSize;
  170.  
  171.   nocache:=Size>FastMoveCacheLimit;
  172.   if reverse then begin
  173.     system.Move(pointer(pDstInnerEnd+delta)^,pointer(pDstInnerEnd)^,pDstEnd-pDstInnerEnd);
  174.     if nocache then _SSE_Move64_rev_nocache(pointer(pDstInner),pointer(pDstInnerEnd),delta)
  175.                else _SSE_Move64_rev_cache  (pointer(pDstInner),pointer(pDstInnerEnd),delta);
  176.     system.Move(Src,Dst,pDstInner-pDst);
  177.   end else begin
  178.     system.Move(Src,Dst,pDstInner-pDst);
  179.     if nocache then _SSE_Move64_fwd_nocache(pointer(pDstInner),pointer(pDstInnerEnd),delta)
  180.                else _SSE_Move64_fwd_cache  (pointer(pDstInner),pointer(pDstInnerEnd),delta);
  181.     system.Move(pointer(pDstInnerEnd+delta)^,pointer(pDstInnerEnd)^,pDstEnd-pDstInnerEnd);
  182.   end;
  183. end;
  184.  
  185. ////////////////////////////////////////////////////////////////////////////////
  186. ///  FastMove Functional and performance test                                 ///
  187. ////////////////////////////////////////////////////////////////////////////////
  188.  
  189. function _TestFastMove:ansistring;
  190.  
  191.   procedure log(s:ansistring);begin result:=result+s+#13#10;writeln(s)end;
  192.  
  193. const TestDataSize=256;
  194.       BufSize=128 shl 20;
  195.  
  196. type TByteArray=array[0..BufSize-1]of byte;PByteArray=^TByteArray;
  197.  
  198. var
  199.   _buf:array of byte;
  200.   buf:PByteArray;
  201.   i,j,k:integer;
  202.   pref,psrc,pdst:pointer;
  203.   siz,alignMask,TestDataSizeBig:integer;
  204.   rate:single;
  205.   bestrate:array[0..7]of single;
  206.   t0,t1,tf:int64;
  207.   s:ansistring;
  208. begin
  209.   result:='';randseed:=0;
  210.   //functional test
  211.   alignMask:=$fff;
  212.   setlength(_buf,BufSize+alignMask);
  213.   buf:=pointer((integer(_buf)+alignMask)and not alignMask);
  214.   //buf:4K aligned 256megs
  215.  
  216.   //test small blocks with various src/dst offsets and sizes
  217.   TestDataSizeBig:=FastMoveCacheLimit+1;
  218.   for i:=0 to TestDataSizeBig-1 do buf[i]:=i*251;//reference data
  219.   for i:=-64 to 64 do for j:=-64 to 64 do for k:=0 to TestDataSize do begin
  220.     if k=TestDataSize then
  221.       if((i or j) and $1f)<>0 then continue;//only a few shifts for big blocks
  222.  
  223.     pref:=@buf[0];
  224.     psrc:=@buf[BufSize shr 1+i];
  225.     pdst:=@buf[BufSize shr 1+j];
  226.     if k=TestDataSize then siz:=TestDataSizeBig//big data a vegen
  227.                       else siz:=k;
  228.  
  229.     System.Move(pref^,psrc^,siz);
  230.     FastMove(psrc^,pdst^,siz);
  231.     if not sysutils.CompareMem(pref,pdst,siz)then begin
  232. //      System.Move(pref^,psrc^,siz);FastMove(psrc^,pdst^,siz);}//reproduce last error for debugging
  233.       raise Exception.CreateFmt('TestFastMove() functional test failed %p %p %x',[psrc,pdst,siz]);
  234.     end;
  235.   end;
  236.  
  237.   //Benchmark
  238.   SetPriorityClass(GetCurrentProcess,REALTIME_PRIORITY_CLASS);
  239.  
  240.   log(Format('%10s%8s%8s%7s%8s%8s%7s%8s%8s%7s%8s%8s%7s',
  241.     ['Size','AASys','AAFast','AAGain','UASys','UAFast','UAGain','AUSys','AUFast','AUGain','UUSys','UUFast','UUGain']));
  242.   siz:=1;
  243.   while siz<=bufsize shr 1 do begin
  244.  
  245.     for k:=0 to 1 do //repeat full test
  246.     for i:=0 to high(bestrate) do begin
  247.  
  248.       bestrate[i]:=0;
  249.       for j:=0 to 7 do begin
  250.  
  251.         QueryPerformanceCounter(t0);
  252.  
  253.         case i and 1 of  //bit0:Fast or not
  254.           0:System.Move(buf[0+i shr 1 and 1],buf[bufsize shr 1-(i shr 2 and 1)*3],siz);
  255.           else FastMove(buf[0+i shr 1 and 1],buf[bufsize shr 1-(i shr 2 and 1)*3],siz);
  256.         end;                //Bit1:srcalign  //Bit2:dstAlign
  257.  
  258.         QueryPerformanceCounter(t1);
  259.         QueryPerformanceFrequency(tf);
  260.         rate:=siz*(tf/(t1-t0))/(1024*1024);
  261.         if bestrate[i]<rate then bestrate[i]:=rate;
  262.       end;
  263.     end;
  264.  
  265.     s:=format('%10d',[siz]);
  266.     for i:=0 to high(bestrate)do begin
  267.       s:=s+format('%8.0f',[bestRate[i]]);
  268.       if(i and 1)<>0 then
  269.         s:=s+format('%7.3f',[bestRate[i]/bestRate[i-1]]);
  270.     end;
  271.     log(s);
  272.  
  273.     if siz<4 then inc(siz)
  274.              else if(siz and(siz shr 1))<>0 then siz:=siz*4 div 3
  275.                                             else siz:=siz*3 div 2;
  276.   end;
  277. end;
  278.  
  279. const fn='FastMove.txt';
  280. var f:TextFile;
  281. begin
  282.   try
  283.     writeln('SSE FastMove tester.');
  284.     writeln('Running test (this could take 10 or more seconds)...');
  285.     AssignFile(f,fn);rewrite(f);Write(f,_TestFastMove);closefile(f);
  286.  
  287.     writeln('All speeds in MByte/sec, AA means 16byte aligned source and destination memory locations, U means unaliged src and/or dst.');
  288.     writeln('(Note that the last unaligned results for system.move are significally slower due to the overlapped source and destination buffer. In that case data have to be moved in reverse direction and system.move is not using cache prefetch hints.)');
  289.     writeln('Results saved in ['+fn+']');
  290.     writeln('Press Enter to exit');
  291.     readln;
  292.   except
  293.     on E: Exception do
  294.       Writeln(E.ClassName, ': ', E.Message);
  295.   end;
  296. end.
Advertisement
Add Comment
Please, Sign In to add comment