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

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h