关于SSE优化内存拷贝的问题
肖尧19 2009-08-06 03:11:45 小弟汇编基础比较差,因工作需求需要实现一个内存拷贝优化的函数
自己参考资料写了个(思路比较简单 1次用够8个128bit的寄存器循环移动数据)
各位看看还有没有优化空间
另外主要的问题是 根据实际测试 结果 大于2M的数据 循环拷贝1000次 大概比memcpy快一倍
但是小于2M的数据块 就都比memcpy慢了 小块数据是否也有可能优化出比memcpy更佳的性能?
void memcpySSE(void* dest,const void* src,size_t _size)
{
__asm
{
//首先检测src地址是否16byte对齐
mov eax,src;
mov ebx,16;
mov edx,0;
div ebx;
cmp edx,0;
//edx非0则跳转
jnz addr_unaligned;
//采用地址对齐mov指令
//addr_aligned:
//数据块是否按128byte对齐
mov eax,_size;
mov ebx,128;
mov edx,0;
div ebx;
mov esi,src;
mov edi,dest;
aligned_loop:
//数据预取 32byte偏移的寻址 添充128byte的CPU CACHE
prefetchnta 128[ESI];
prefetchnta 160[ESI];
prefetchnta 192[ESI];
prefetchnta 224[ESI];
movdqa xmm0,0[ESI];//src to 寄存器
movdqa xmm1,16[ESI];
movdqa xmm2,32[ESI];
movdqa xmm3,48[ESI];
movdqa xmm4,64[ESI];
movdqa xmm5,80[ESI];
movdqa xmm6,96[ESI];
movdqa xmm7,112[ESI];
movntdq 0[EDI],xmm0;//寄存器 to dst
movntdq 16[EDI],xmm1;
movntdq 32[EDI],xmm2;
movntdq 48[EDI],xmm3;
movntdq 64[EDI],xmm4;
movntdq 80[EDI],xmm5;
movntdq 96[EDI],xmm6;
movntdq 112[EDI],xmm7;
add esi,128;
add edi,128;
dec eax;
jnz aligned_loop;
//aligned_loop_end:
//如果edx非0 操作剩余byte
mov ecx,edx;
rep movsb;
jmp memcpy_sse_end;
addr_unaligned:
mov eax,_size;
mov ebx,128;
mov edx,0;
div ebx;
mov esi,src;
mov edi,dest;
unaligned_loop:
prefetchnta 128[ESI];
prefetchnta 160[ESI];
prefetchnta 192[ESI];
prefetchnta 224[ESI];
movdqu xmm0,0[ESI];//src to 寄存器
movdqu xmm1,16[ESI];
movdqu xmm2,32[ESI];
movdqu xmm3,48[ESI];
movdqu xmm4,64[ESI];
movdqu xmm5,80[ESI];
movdqu xmm6,96[ESI];
movdqu xmm7,112[ESI];
movntdq 0[EDI],xmm0;//寄存器 to dst
movntdq 16[EDI],xmm1;
movntdq 32[EDI],xmm2;
movntdq 48[EDI],xmm3;
movntdq 64[EDI],xmm4;
movntdq 80[EDI],xmm5;
movntdq 96[EDI],xmm6;
movntdq 112[EDI],xmm7;
add esi,128;
add edi,128;
dec eax;
jnz unaligned_loop;
//unaligned_loop_end:
mov ecx,edx;
rep movsb;
memcpy_sse_end:
}
}