当前位置: 代码迷 >> 汇编语言 >> 求教一个VC内嵌汇编的函数用来代替memset的,该怎么解决
  详细解决方案

求教一个VC内嵌汇编的函数用来代替memset的,该怎么解决

热度:7129   发布时间:2013-02-26 00:00:00.0
求教一个VC内嵌汇编的函数用来代替memset的
void asmmemset(void *destmem,int c,int length) //据说快过memset();mov ecx, length
{
__asm 
{
movq mm0, c
punpcklbw mm0, mm0
punpcklwd mm0, mm0
punpckldq mm0, mm0
mov edi, destmem

mov ecx, length
lea edi, DWORD PTR [edi+ecx*8]
neg ecx

movq mm1, mm0
movq mm2, mm0
movq mm3, mm0
movq mm4, mm0
movq mm5, mm0
movq mm6, mm0
movq mm7, mm0

loopwrite:
movntq [edi + ecx * 8 ], mm0
movntq [edi + ecx * 8 + 8 ], mm1
movntq [edi + ecx * 8 + 16], mm2
movntq [edi + ecx * 8 + 24], mm3
movntq [edi + ecx * 8 + 32], mm4
movntq [edi + ecx * 8 + 40], mm5
movntq [edi + ecx * 8 + 48], mm6
movntq [edi + ecx * 8 + 56], mm7

add ecx, 8
jnz loopwrite

emms
}
}
这个函数据说速度要快过memset,但是
{
QueryPerformanceCounter(&litmp); 
QPart1 = litmp.QuadPart;// 获得初始值 

//测试代码1
memset(ptemp[1],0,80*80);

QueryPerformanceCounter(&litmp); 
QPart2 = litmp.QuadPart;//获得中止值 
dfMinus = (double)(QPart2-QPart1); 
}
{
QueryPerformanceCounter(&litmp); 
QPart1 = litmp.QuadPart;// 获得初始值 

//测试代码2
asmmemset(ptemp[0],1,80*80/8);
QueryPerformanceCounter(&litmp); 
QPart2 = litmp.QuadPart;//获得中止值 
dfMinus -= (double)(QPart2-QPart1); 
}
测了一下,毫无效果啊,而且更慢,是不是这个函数过时了啊,有高手能提供个更好的吗?或者给讲讲怎么改什么的
谢谢

------解决方案--------------------------------------------------------
应该不会,MMX是64位寄存器,如果在32位的CPU应该是比较快的
------解决方案--------------------------------------------------------
三个问题:

1. 设计上与C库memset不兼容,(a) length在memset中是一字节为单位的长度,这个函数则以64位字为单位;(b) 标准memset返回*destmem,这个函数没有返回。

2. 每次[edi + ecx * 8 + 8]之类的地址计算降低了性能。

3. movntq只对大块内存写能提高性能,小块写的话不如写到cache的性能。