由于性能上的需要,不得不用MMX来优化速度
由于之前只是学过MMX,没实际写过,就从网上google了一下……
以“mmx 内存拷贝”为关键字,找到很多文章,都是互相抄的,例如第一个结果:
【内存拷贝的优化方法】
内存拷贝的优化方法. [本页面推荐在1024x768分辩率下浏览] 文章类别:Visual C++.
www.zahui.com/html/1/3506.htm
恩……看起来不错,于是我就复制下来,结果不能用,bug阿bug……晕倒!
看来国人抄袭的水平见涨,真本事倒不见得有什么进步,只好自己修改一下了!文章里面是nsam,我把它改成了Visual C++的内联汇编同时改正了bug,添加了必要的指令,就是下面这样,有兴趣的朋友可以和原来的代码比较一下:
void _fast_memcpy6(void* dst, void* src, int len)
{
_asm
{
push esi
push edi
push edx
mov esi, [src] ; source array
mov edi, [dst] ; destination array
mov ecx, [len] ; number of QWORDS (8 bytes) assumes len / CACHEBLOCK is an integer
shr ecx, 6
mov edx, 0
nop;lea esi, [esi+ecx*8] ; end of source
nop;lea edi, [edi+ecx*8] ; end of destination
neg ecx ; use a negative offset as a combo pointer-and-loop-counter
copyloop:
movq mm0, [esi+edx*8]
movq mm1, [esi+edx*8+8]
movq mm2, [esi+edx*8+16]
movq mm3, [esi+edx*8+24]
movq mm4, [esi+edx*8+32]
movq mm5, [esi+edx*8+40]
movq mm6, [esi+edx*8+48]
movq mm7, [esi+edx*8+56]
movq [edi+edx*8], mm0
movq [edi+edx*8+8], mm1
movq [edi+edx*8+16], mm2
movq [edi+edx*8+24], mm3
movq [edi+edx*8+32], mm4
movq [edi+edx*8+40], mm5
movq [edi+edx*8+48], mm6
movq [edi+edx*8+56], mm7
add edx, 8
add ecx, 1
jnz copyloop
emms
pop edx
pop edi
pop esi
}
}
实际结果却没有那么令人振奋,用Visual C++自带的memcpy,复制256000字节,速度大约是
QueryPerformanceFrequency 3579545
QueryPerformanceCounter Before 84359650011
QueryPerformanceCounter After 84359651509 (delta 1500)
用这个MMX的,速度大约是
QueryPerformanceFrequency 3579545
QueryPerformanceCounter Before 84503893730
QueryPerformanceCounter After 84503894930 (delta 1200)
也就是有20%左右的提高