高速なmemcpyの実装に関する話題

http://www.cyborg.ne.jp/~xelf/developer/MemoryCopy.html
http://d.hatena.ne.jp/kmt-t/20040629#p3
http://d.hatena.ne.jp/shinichiro_h/20040616#p1
http://d.hatena.ne.jp/studiokingyo/20040719
http://beautiful.homelinux.net/~sky-software/diary/?date=20040801
http://beautiful.homelinux.net/~sky-software/diary/?date=20040910


sky氏が製作したソースコードを元に自らのソースを加えて計測しました。*1


確保したメモリ 31458980 * 2
コピーするサイズ:30.000000MByte 繰り返す回数:100
memcpy 10.143000 秒 302868 kb/sec
memcpy_ 11.608000 秒 264645 kb/sec
memcpy__ 11.637000 秒 263985 kb/sec
memcpy_rep1 10.871000 秒 282586 kb/sec
memcpy_rep2 10.731000 秒 286273 kb/sec
dkcstd_memcpy32 10.203000 秒 301087 kb/sec(intでコピー)
dkcstd_memcpy64f 10.418000 秒 294874 kb/sec (double *でコピー)
dkcstd_memcpy64 10.541000 秒 291433 kb/sec (ULONGLONG *でコピー)
memmove 9.716000 秒 316179 kb/sec
dkcstd_memmove 9.717000 秒 316146 kb/sec (GreenPadの実装)


http://beautiful.homelinux.net/~sky-software/diary/?date=20050124
にて、この記事に関する話題が・・・。
え!DGCAってマイナー!!?という事実が発覚!! ORZ Orz orz Orz orz...
個人的には凄くメジャーな圧縮形式だと思って、使っていました。
すみません (_ _(--;(_ _(--; ペコペコ

次回からはzip dgcaをアップ・・・ですか。
その為の一発指定で両方吐いてくれるスクリプト組まなければ・・・むぅ。


資料として、以下が私が組んだmemcpyのC言語版のアセ値


191: void *dkcstd_memcpy( void *dest, const void *src, size_t count ){
00422900 push ebp
00422901 mov ebp,esp
00422903 sub esp,54h
00422906 push ebx
00422907 push esi
00422908 push edi
00422909 lea edi,[ebp-54h]
0042290C mov ecx,15h
00422911 mov eax,0CCCCCCCCh
00422916 rep stos dword ptr [edi]
192:
193: size_t i;
194: size_t *d,*s;
195: size_t cnt = count / sizeof(size_t);
00422918 mov eax,dword ptr [ebp+10h]
0042291B shr eax,2
0042291E mov dword ptr [ebp-10h],eax
196: size_t mod_ = count - cnt * sizeof(size_t);
00422921 mov eax,dword ptr [ebp-10h]
00422924 shl eax,2
00422927 mov ecx,dword ptr [ebp+10h]
0042292A sub ecx,eax
0042292C mov dword ptr [ebp-14h],ecx
197: d = (size_t *)dest;
0042292F mov eax,dword ptr [ebp+8]
00422932 mov dword ptr [ebp-8],eax
198: s = (size_t *)src;
00422935 mov eax,dword ptr [ebp+0Ch]
00422938 mov dword ptr [ebp-0Ch],eax
199: for(i=0;i<cnt;i++){
0042293B mov dword ptr [ebp-4],0
00422942 jmp dkcstd_memcpy+4Dh (0042294d)
00422944 mov eax,dword ptr [ebp-4]
00422947 add eax,1
0042294A mov dword ptr [ebp-4],eax
0042294D mov eax,dword ptr [ebp-4]
00422950 cmp eax,dword ptr [ebp-10h]
00422953 jae dkcstd_memcpy+69h (00422969)
200: d[i] = s[i];
00422955 mov eax,dword ptr [ebp-4]
00422958 mov ecx,dword ptr [ebp-8]
0042295B mov edx,dword ptr [ebp-4]
0042295E mov esi,dword ptr [ebp-0Ch]
00422961 mov edx,dword ptr [esi+edx*4]
00422964 mov dword ptr [ecx+eax*4],edx
201: }
00422967 jmp dkcstd_memcpy+44h (00422944)
202:
203: cnt = count - mod_;
00422969 mov eax,dword ptr [ebp+10h]
0042296C sub eax,dword ptr [ebp-14h]
0042296F mov dword ptr [ebp-10h],eax
204: for(i=0;i<mod_;i++){
00422972 mov dword ptr [ebp-4],0
00422979 jmp dkcstd_memcpy+84h (00422984)
0042297B mov eax,dword ptr [ebp-4]
0042297E add eax,1
00422981 mov dword ptr [ebp-4],eax
00422984 mov eax,dword ptr [ebp-4]
00422987 cmp eax,dword ptr [ebp-14h]
0042298A jae dkcstd_memcpy+0A6h (004229a6)
205: (((uint8 *)dest)[cnt + i]) = (((const uint8 *)src)[cnt + i]);
0042298C mov eax,dword ptr [ebp-10h]
0042298F add eax,dword ptr [ebp-4]
00422992 mov ecx,dword ptr [ebp-10h]
00422995 add ecx,dword ptr [ebp-4]
00422998 mov edx,dword ptr [ebp+8]
0042299B mov esi,dword ptr [ebp+0Ch]
0042299E mov al,byte ptr [esi+eax]
004229A1 mov byte ptr [edx+ecx],al
206: }
004229A4 jmp dkcstd_memcpy+7Bh (0042297b)
207: return dest;
004229A6 mov eax,dword ptr [ebp+8]
208: }
004229A9 pop edi
004229AA pop esi
004229AB pop ebx
004229AC mov esp,ebp
004229AE pop ebp
004229AF ret
209:
長くて (_ _(--;(_ _(--; ペコペコ

*1:アセンブラの実装の方はFPUとsse系のバグが取れていないので計測していません。次回に計測する予定です。