SSE的代码速度就一定快吗(附测试代码),不解

lytsky521 2009-02-18 03:01:30
#include "windows.h"
#include <xmmintrin.h>
void MemCopySSE(LPVOID pDest, LPVOID pSrc, int nSize)
{
int nSSESize = nSize >> 4;
int nTemp = nSSESize << 4;
nSize -= nTemp;
if(nSSESize)
{
__asm
{
push ecx
push edx
push eax
mov eax, [pSrc]
mov edx, [pDest]
mov ecx, [nSSESize]
memcpy_process:
movups xmm0, [eax]
add eax, 10h
movups [edx], xmm0
add edx, 10h
dec ecx
jnz memcpy_process
pop eax
pop edx
pop ecx
emms
}
}
if(nSize)
{
memcpy((BYTE *)pDest + nTemp, (BYTE *)pSrc + nTemp, nSize);
}
}

void memcpy_sse(BYTE* pDest, const BYTE* pSrc, size_t nBytes )
{
void* pDestOrg = pDest;

UINT nAlignDest = (16 - (uintptr_t)pDest) & 15;
memcpy( pDest, pSrc, nAlignDest );
pDest += nAlignDest;
pSrc += nAlignDest;
nBytes -= nAlignDest;

UINT nLoops = nBytes >> 6; // no. of loops to copy 64 bytes
nBytes -= nLoops << 6;
if( ((uintptr_t)pSrc & 15) == 0 )
{
for( int i = nLoops; i > 0; --i )
{
__m128 tmp0 = _mm_load_ps( (float*)(pSrc + 0 ) );
__m128 tmp1 = _mm_load_ps( (float*)(pSrc + 16) );
__m128 tmp2 = _mm_load_ps( (float*)(pSrc + 32) );
__m128 tmp3 = _mm_load_ps( (float*)(pSrc + 48) );
_mm_store_ps( (float*)(pDest + 0 ), tmp0 );
_mm_store_ps( (float*)(pDest + 16), tmp1 );
_mm_store_ps( (float*)(pDest + 32), tmp2 );
_mm_store_ps( (float*)(pDest + 48), tmp3 );
pSrc += 64;
pDest += 64;
}
}
else
{
for( int i = nLoops; i > 0; --i )
{
__m128 tmp0 = _mm_loadu_ps( (float*)(pSrc + 0 ) );
__m128 tmp1 = _mm_loadu_ps( (float*)(pSrc + 16) );
__m128 tmp2 = _mm_loadu_ps( (float*)(pSrc + 32) );
__m128 tmp3 = _mm_loadu_ps( (float*)(pSrc + 48) );
_mm_store_ps( (float*)(pDest + 0 ), tmp0 );
_mm_store_ps( (float*)(pDest + 16), tmp1 );
_mm_store_ps( (float*)(pDest + 32), tmp2 );
_mm_store_ps( (float*)(pDest + 48), tmp3 );
pSrc += 64;
pDest += 64;
}
}
memcpy( pDest, pSrc, nBytes);
}

int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwSrc[5120];
DWORD dwDes[5120];

DWORD s1=1, e1=2, s2=3, e2=4, s3 = 5, e3 = 6;
s1 = GetTickCount();
for (int i = 0; i < 100000; i++)
memcpy(dwDes, dwSrc, sizeof(dwSrc));
e1 = GetTickCount();
s2 = GetTickCount();
for (int i = 0; i < 100000; i++)
MemCopySSE(dwDes, dwSrc, sizeof(dwSrc));
e2 = GetTickCount();
s3 = GetTickCount();
for (int i = 0; i < 100000; i++)
memcpy_sse((BYTE *)dwDes, (BYTE *)dwSrc, sizeof(dwSrc));
e3 = GetTickCount();

TCHAR s[64];
_stprintf(s, _T("%d-%d-%d"), e1-s1, e2-s2, e3-s3);
MessageBox(0, s, 0, 0);
return 0;
}


如题,本人的机器cpu pD2.8,xp sp3,测试结果531-578-1703,memcpy代码摘自网页,大家的测试结果是怎样的呢
...全文
349 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
Big_Stone 2011-05-02
  • 打赏
  • 举报
回复
这个东西不好说首先你的测试不准确5K的数据量不能看出问题来,因为5K拷贝花费的时间用的时间估计还没有你采用TICK计时的误差大。
csgdseed 2009-02-20
  • 打赏
  • 举报
回复
关注
lytsky521 2009-02-19
  • 打赏
  • 举报
回复
毕竟是特意地写了SSE版内存拷贝的函数,个人认为是在大内存时,两内存块地址相差较远的情况下才SSE内存操作会有优势,不知道这个解释是否合理。继续等待最佳答案
会思考的草 2009-02-19
  • 打赏
  • 举报
回复
同意ls诸位。
SSE加速的是运算,访存的瓶颈是硬件。
DarknessTM 2009-02-19
  • 打赏
  • 举报
回复
MMX SSE SSE2 等等 应该加速的是计算 而不是数据复制……

如采用MMX的 alpha混合
jyh_baoding 2009-02-19
  • 打赏
  • 举报
回复
顶一个
jxufeng 2009-02-18
  • 打赏
  • 举报
回复
我们的计算机都是32位的(现在是64位吧),奔腾(k6)刚出来那会,32位计算一些东西如多媒体处理什么的速度很慢,厂商就加了几个64位的寄存器,称为mmx,后来又加了sse2,现在的sse3好像128位,这样就可以同时算好几个数,比如32位处理图像一次只能处理一个点,64位就可以处理两个甚至3个点了,所以速度会加快的,同理对于有些大数据量的运算,同时处理两个数据会有效率的提高。
搞图形图像的人好像用这个比较多。此外,vs2008里面有关于mmx的专门函数(写好了的静态库),可以看看。
看这段代码,似乎sse会有高效率。本人也是半吊子,还是多查些汇编的资料吧。
菜牛 2009-02-18
  • 打赏
  • 举报
回复
不一定的,对于内存拷贝操作SSE应该是无能为力的。
会思考的草 2009-02-18
  • 打赏
  • 举报
回复
mark一下,明天来测一下
danxuezx 2009-02-18
  • 打赏
  • 举报
回复
学习
stuarts740 2009-02-18
  • 打赏
  • 举报
回复
什么是SSE?

16,470

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧