可爱的,可恨的,奇怪的 memset().........

iamnobody 2011-08-26 02:16:08


#include<iostream>
#include<iomanip>
#include<time.h>
#include<vector>
#include<algorithm>
#include<iterator>
#include<numeric>
using namespace std;

int main(int argc,char* argv[])
{


int SIZE = 1024*1024*64;
int val = 0x0f0f0f0f;
int *buf = new int[SIZE];
clock_t beg = clock();
memset(buf,val,SIZE);
clock_t memset_fun = clock();

for(int i = 0; i < SIZE; i++)
buf[i] = val;

clock_t for_loop = clock();

cout<<"memset function: "<<memset_fun - beg<<endl<<"for loop: "<<for_loop - memset_fun;
cout<<hex<<endl<<buf[0]<<endl;
cout<<endl<<(((int)buf) & 3)<<endl;
system("pause");
return 0;
}



输出结果是:
memset function: 61
for loop: 288
f0f0f0f0

0


问题是:
memset()比for 循环快很正常,但是我的是在release 状态下测试的,且看反汇编:


18: clock_t beg = clock();
003E1045 mov edi,dword ptr [__imp__clock (3E20D4h)]
003E104B add esp,4
003E104E mov esi,eax
003E1050 call edi
19: memset(buf,val,SIZE);
003E1052 push 4000000h
003E1057 push 0F0F0F0Fh
003E105C push esi
003E105D mov dword ptr [esp+18h],eax
003E1061 call memset (3E1C2Ah)
003E1066 add esp,0Ch
20: clock_t memset_fun = clock();
003E1069 call edi
003E106B mov ebx,eax
21:
22: for(int i = 0; i < SIZE; i++)
23: buf[i] = val;
003E106D mov eax,0F0F0F0Fh
003E1072 mov ecx,4000000h
003E1077 mov edi,esi
003E1079 rep stos dword ptr es:[edi]
24:
25: clock_t for_loop = clock();
003E107B call dword ptr [__imp__clock (3E20D4h)]




注意倒数等四行:我的for 循环已经被优化成了rep stos dword ptr es:[edi]
这个跟memset()里面的核心语句是一样的。而且,输出结果表明指针的确是在4字节整数倍上的,单步跟踪也发现memset()并没有做什么特别的动作才执行rep stosd 。 可是为什么??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
为什么memset()就是要比我的for循环快???????而且多次测试结果表明,for循环用的时间是memset()的6-3倍?????????????????????????????????????



为什么???????????????????????????



注:也不是clock()函数的影响。

大牛快回答啊。
...全文
193 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
孤独小剑 2011-08-26
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 0153 的回复:]

引用 7 楼 ljljlj 的回复:

你在循环里要置0的空间大小是memset里的4倍!

在memset里的SIZE指的是字节。
在for里SIZE指的是双字。

在vc6.0下它们生成的代码是模一样的!只是指定的SIZE大小一个是0x1000000,另一个是0x4000000

正解,lz应该改成memset(buf,val,SIZE*sizeof(int));
[/Quote]
学习,正解……
赵4老师 2011-08-26
  • 打赏
  • 举报
回复
memset(buf,val,SIZE);
应改为
memset(buf,0x0f,SIZE*sizeof(int));
赵4老师 2011-08-26
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 ljljlj 的回复:]
你在循环里要置0的空间大小是memset里的4倍!

在memset里的SIZE指的是字节。
在for里SIZE指的是双字。

在vc6.0下它们生成的代码是模一样的!只是指定的SIZE大小一个是0x1000000,另一个是0x4000000
[/Quote]
事实的确如此。
0153 2011-08-26
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 ljljlj 的回复:]

你在循环里要置0的空间大小是memset里的4倍!

在memset里的SIZE指的是字节。
在for里SIZE指的是双字。

在vc6.0下它们生成的代码是模一样的!只是指定的SIZE大小一个是0x1000000,另一个是0x4000000
[/Quote]
正解,lz应该改成memset(buf,val,SIZE*sizeof(int));
ljhhh0123 2011-08-26
  • 打赏
  • 举报
回复
你在循环里要置0的空间大小是memset里的4倍!

在memset里的SIZE指的是字节。
在for里SIZE指的是双字。

在vc6.0下它们生成的代码是模一样的!只是指定的SIZE大小一个是0x1000000,另一个是0x4000000
pengzhixi 2011-08-26
  • 打赏
  • 举报
回复
未必memset用的就是你看到的那个程序。也许用的是一个内嵌版本的。
wintree 2011-08-26
  • 打赏
  • 举报
回复
帮楼主顶了一下~
iamnobody 2011-08-26
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 svcce 的回复:]
混个脸熟!
[/Quote]

怎么我换不了头像?
又要沉了,顶!!!!!
iamnobody 2011-08-26
  • 打赏
  • 举报
回复
不要沉了,大家帮忙顶啊!
iamnobody 2011-08-26
  • 打赏
  • 举报
回复
vs 2010 编译的。。
VS 2010 从来不内联 memset()
难道有什么阴谋?????????
iamnobody 2011-08-26
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 ljljlj 的回复:]
你在循环里要置0的空间大小是memset里的4倍!

在memset里的SIZE指的是字节。
在for里SIZE指的是双字。

在vc6.0下它们生成的代码是模一样的!只是指定的SIZE大小一个是0x1000000,另一个是0x4000000
[/Quote]


我2了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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