本来自己写了一个,不过性能竟然和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字节也许性能能提高更多。