memcpy を MMX とか SSE とかで
http://d.hatena.ne.jp/ytqwerty/20040616#p1 より
計算するならともかく単なる転送で速くなるんかなあ…
環境は Celeron 1.7GHz, MMX, SSE, SSE2 が使える。
#include#include enum { TIMES = 100, SIZE = 1000000, SIZE_2 = 500000, SIZE_4 = 250000 }; int main() { int src[SIZE]__attribute__*1; srcp+=2; dstp+=2; } */ /* 890000 for (i = 0; i < SIZE_2; i++) { asm("movq (%0), %%mm0;" "movq %%mm0, (%1);" :: "r"(srcp), "r"(dstp)); srcp+=2; dstp+=2; } */ /* 890000 for (i = 0; i < SIZE_4; i++) { asm("movaps (%0), %%xmm0;" "movaps %%xmm0, (%1);" :: "r"(srcp), "r"(dstp)); srcp+=4; dstp+=4; } */ /* 900000 for (i = 0; i < SIZE; i+=16) { asm("movaps (%0), %%xmm0;" "movaps %%xmm0, (%1);" "movaps 16(%0), %%xmm0;" "movaps %%xmm0, 16(%1);" "movaps 32(%0), %%xmm0;" "movaps %%xmm0, 32(%1);" "movaps 48(%0), %%xmm0;" "movaps %%xmm0, 48(%1);" :: "r"(srcp), "r"(dstp)); srcp+=16; dstp+=16; } */ } printf("%d\n", clock() - c); srcp = src; dstp = dst; for (i = 0; i < SIZE; i++) { if (*dstp++ != *srcp++) { printf("%d err\n", i); return 1; } } return 0; }
コメントの直後の数字が clock 使って表示された数値。よーするに movntq でメモリに書き出したやつだけおどろくほど速かったです。なんでかとかはまあどうでもいいや。あと MMX 命令っていっぱいあるけどどれがはやいかとかよく知りません。
なんて書いてたら http://d.hatena.ne.jp/ytqwerty/20040616#p2 で、 http://www.cyborg.ne.jp/~xelf/developer/MemoryCopy.html が紹介されてるし。
ええと、 CLOCKS_PER_SEC は 1000000 です。つまりこんだけ転送しても問題ない速度ですね。あと gcc のインラインアセンブラです。
*1:aligned(16))); int dst[SIZE]__attribute__((aligned(16))); int i, j; int *srcp = src; int *dstp = dst; clock_t c = clock(); for (j = 0; j < TIMES; j++) { srcp = src; dstp = dst; /* 890000 for (i = 0; i < SIZE; i++) *dstp++ = *srcp++; */ /* 390000 for (i = 0; i < SIZE_2; i++) { asm("movq (%0), %%mm0;" "movntq %%mm0, (%1);" :: "r"(srcp), "r"(dstp