多媒体指令(内存拷贝加速)

本来自己写了一个,不过性能竟然和memcpy一样,一点提升都没有,所以有就去网上找了一个性能好的。

下面的程序是对100MB数据进行内存拷贝.

我测试了一下。

直接调用memcpy时间为100ms左右,而asm中的程序能把时间能缩短到80ms左右。

性能提高的还是很明显的。

#include <iostream>
#include <ctime>
#define  N 100*1024*256

using namespace std;

int main(int argc, char* argv[])
{
    float *a;
    float *b;
    a=(float*)malloc(N*sizeof(float));
    b=(float*)malloc(N*sizeof(float));
    for (unsigned long i=0;i<N;++i)
    {
        a[i]=rand();
    }
    unsigned long n=N*sizeof(float);
    void *tbuf;
    tbuf=(void*)malloc(2048);

    time_t start,end;
    start=clock();

//    memcpy(b,a,N*sizeof(float));    
    __asm {
            mov esi, [a]
            mov ecx, n
            mov ebx, ecx
            shr ebx, 11 // 2048 bytes at a time
            mov edi, [b]

    loop2k: // Copy 2k into temporary buffer
            push edi
            mov edi, tbuf
            mov ecx, 2048
            shr ecx, 6

    loopMemToL1:
            prefetchnta 64[esi] // Prefetch next loop, non-temporal
            prefetchnta 96[esi]

            movq mm1,  0[esi] // Read in source data
            movq mm2,  8[esi]
            movq mm3, 16[esi]
            movq mm4, 24[esi]
            movq mm5, 32[esi]
            movq mm6, 40[esi]
            movq mm7, 48[esi]
            movq mm0, 56[esi]

            movq  0[edi], mm1 // Store into L1
            movq  8[edi], mm2
            movq 16[edi], mm3
            movq 24[edi], mm4
            movq 32[edi], mm5
            movq 40[edi], mm6
            movq 48[edi], mm7
            movq 56[edi], mm0
            add esi, 64
            add edi, 64
            dec ecx
            jnz loopMemToL1

            pop edi // Now copy from L1 to system memory
            push esi
            mov esi, tbuf
            mov ecx, 2048
            shr ecx, 6

    loopL1ToMem:
            movq mm1, 0[esi] // Read in source data from L1
            movq mm2, 8[esi]
            movq mm3, 16[esi]
            movq mm4, 24[esi]
            movq mm5, 32[esi]
            movq mm6, 40[esi]
            movq mm7, 48[esi]
            movq mm0, 56[esi]

            movntq 0[edi], mm1 // Non-temporal stores
            movntq 8[edi], mm2
            movntq 16[edi], mm3
            movntq 24[edi], mm4
            movntq 32[edi], mm5
            movntq 40[edi], mm6
            movntq 48[edi], mm7
            movntq 56[edi], mm0

            add esi, 64
            add edi, 64
            dec ecx
            jnz loopL1ToMem

            pop esi // Do next 2k block
            dec ebx
            jnz loop2k
            emms;
    }
        
    end=clock();
    cout<<end-start<<endl;
    for (unsigned long i=N-10;i<N;i++)
    {
        cout<<a[i]<<"  "<<b[i]<<endl;
    }

    free(a);
    free(b);
    free(tbuf);
    system("pause");
    return 0;
}

也可以尝试一下xmm寄存器,一次移动128字节也许性能能提高更多。

 

posted @ 2013-03-17 21:42  Dsp Tian  阅读(1052)  评论(0编辑  收藏  举报