游戏开发论坛

 找回密码
 立即注册
搜索
查看: 5339|回复: 9

为什么我用sse指令拷贝内存反而变慢了

[复制链接]

42

主题

115

帖子

141

积分

注册会员

Rank: 2

积分
141
发表于 2010-12-14 20:26:00 | 显示全部楼层 |阅读模式
因为需要快速拷贝大量内存,于是我在考虑用不用sse,于是我就照着网上说的先写个简单的代码来对比对比,却发现还不如直接用32位寄存器拷贝快,虽然我写得很粗糙,但是差距也不该那么大啊?

/* 这用了sse指令 */
void memorycpy(void *src, void *des, DWORD len)
{
        _asm
        {
                mov                esi,        src
                mov                edi,        des
                mov                ecx,        len
                shr                ecx,        6
cpyloop:
                prefetchnta                [esi+64]
                movq        mm0,        [esi]
                movq        mm1,        [esi+8]
                movq        mm2,        [esi+16]
                movq        mm3,        [esi+24]
                movq        mm4,        [esi+32]
                movq        mm5,        [esi+40]
                movq        mm6,        [esi+48]
                movq        mm7,        [esi+56]

                movntq        [edi],                mm0
                movntq        [edi+8],        mm1
                movntq        [edi+16],        mm2
                movntq        [edi+24],        mm3
                movntq        [edi+32],        mm4
                movntq        [edi+40],        mm5
                movntq        [edi+48],        mm6
                movntq        [edi+54],        mm7

                add                edi,                64
                add                esi,                64
                loop        cpyloop
               
                sfence
                emms
        }
}

42

主题

115

帖子

141

积分

注册会员

Rank: 2

积分
141
 楼主| 发表于 2010-12-14 20:33:00 | 显示全部楼层

Re:为什么我用sse指令拷贝内存反而变慢了

/*这是一般的拷贝*/
void memmov(void *src, void *des, DWORD len)
{
mov         ecx,len
shr        ecx,2
mov         esi,src
mov         edi,des
rep        movsd
}

0

主题

398

帖子

577

积分

高级会员

Rank: 4

积分
577
发表于 2010-12-14 23:02:00 | 显示全部楼层

Re:为什么我用sse指令拷贝内存反而变慢了

这是一般的内存拷贝吗?你能保证所有的数据长度都是四的倍数?
用汇编就要多看文档,SSE指令在访问4字节对齐内存时效率才是最高的,如果不是对齐的....你就杯具了
1.循环优化中并不一定循环次数越少越好,虽然你在一次循环中拷贝了64个字节,但是相应的,一次循环的指令数变多了,这会增加指令缓冲命中失败的几率,所以适当的减少loop之中的指令可能会提升速度.
2.减少"prefetchnta"预取内存的粒度试试,我记得有些CPU 数据Cache行的大小是32字节...
3.直接使用微软的memcpy,这个是才是经过高度优化的!

42

主题

115

帖子

141

积分

注册会员

Rank: 2

积分
141
 楼主| 发表于 2010-12-15 12:37:00 | 显示全部楼层

Re: Re:为什么我用sse指令拷贝内存反而变慢了

artint: Re:为什么我用sse指令拷贝内存反而变慢了

这是一般的内存拷贝吗?你能保证所有的数据长度都是四的倍数?
用汇编就要多看文档,SSE指令在访问4字节对齐内...


src 与 des我是在全局申明的静态数字,应该会被编译器自动字节对齐吧?1楼的代码我是照着网上普遍的说能很快的代码依葫芦画瓢,再怎么说也不会比 movsd慢吧?还有memcpy编译后就是我2楼的代码

0

主题

398

帖子

577

积分

高级会员

Rank: 4

积分
577
发表于 2010-12-15 14:26:00 | 显示全部楼层

Re:为什么我用sse指令拷贝内存反而变慢了

1.我说错了,SSE对16字节对齐的效率最好....
2.可能影响效率的原因我已经解释了,具体原因你还要自己去试验,不同平台不同配置可能会有差别.既然能自己照着写,能自己测速度,为什么不能自己调试呢?自己找到的原因才是正确的,我只是帮你分析"可能"
3.你用的哪里的memcpy?你去找VS2005里面那个memcpy.asm看看,你给出的代码不可能是标准memcpy函数编译的,别的不说,参数顺序都不对,另外举个简单例子,标准memcpy函数能够正确实现如下功能:
BYTE* lpData;
memcpy(lpData + 8, lpData, 1024);
你的代码就无法实现!

42

主题

115

帖子

141

积分

注册会员

Rank: 2

积分
141
 楼主| 发表于 2010-12-15 19:34:00 | 显示全部楼层

Re: Re:为什么我用sse指令拷贝内存反而变慢了

artint: Re:为什么我用sse指令拷贝内存反而变慢了

1.我说错了,SSE对16字节对齐的效率最好....
2.可能影响效率的原因我已经解释了,具体原因你还要自己去试验,...

vc2008,release


void main()
{
00401000  push        esi  
00401001  push        edi  
        memcpy(sr,de,55);
00401002  mov         ecx,0Dh
00401007  mov         esi,offset de (403378h)
0040100C  mov         edi,offset sr (4033B0h)
00401011  rep movs    dword ptr es:[edi],dword ptr [esi]
00401013  movs        word ptr es:[edi],word ptr [esi]
00401015  movs        byte ptr es:[edi],byte ptr [esi]
00401016  pop         edi  
}

0

主题

398

帖子

577

积分

高级会员

Rank: 4

积分
577
发表于 2010-12-15 21:50:00 | 显示全部楼层

Re:为什么我用sse指令拷贝内存反而变慢了

1.参数你用错了
2.不要参考使用静态地址,常量参数并且经过编译器高度优化的代码来举例子
  你用memcpy(dest,src,55), memcpy(dest,src,54), memcpy(dest,src,64)分别编译看看,编出的代码都是不一样的....你这能说明问题吗?
3.测试代码所用的时间,不能使用GetTickCount(),timeGetTime(),或者RDTSC指令,这些都是不准确的

9

主题

132

帖子

145

积分

注册会员

Rank: 2

积分
145
QQ
发表于 2010-12-16 09:00:00 | 显示全部楼层

Re:为什么我用sse指令拷贝内存反而变慢了

        这是mmx的, 用sse或sse2, ms crt的memcpy就是这些的集合. 可以开下memcpy的实现.
sse see2的拷贝要在数据比较多的时候速度才会快, 小块数据直接用movsd好点。
        还有就是字节对齐的, 这个很麻烦的, 还是建议不要用字节对齐的movaps, 我都是用movups,
除非对整体影响很大。 字节对齐在实际使用的时候非常麻烦。

42

主题

115

帖子

141

积分

注册会员

Rank: 2

积分
141
 楼主| 发表于 2010-12-16 09:36:00 | 显示全部楼层

Re:为什么我用sse指令拷贝内存反而变慢了

我看我还是先看看计算机体系结构的书吧,另外感谢二位的回答

0

主题

398

帖子

577

积分

高级会员

Rank: 4

积分
577
发表于 2010-12-16 10:21:00 | 显示全部楼层

Re:为什么我用sse指令拷贝内存反而变慢了

找VS2005的memcpy.asm看下.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-8-17 08:56

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表