memset效率问题

jamesfoo 2008-11-20 09:14:06
unsigned int a[1024];

for(int i=0;i<1024;i++)
a[i]=0x80808080;

memset(a,0x80,1024*sizeof(int));

哪个效率更高?
...全文
1172 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Gdatasheet 2008-11-21
  • 打赏
  • 举报
回复
说这么多干嘛,反汇编你所写的程序,然后把memset也给反汇编了
把他们都变成cpu 指令了,再一条一条的来数(把每条指令的执行时间加起来)就不出来了?

你在这里问这么久,都已经数出来了。
BaihowFF 2008-11-21
  • 打赏
  • 举报
回复
能放到库函数里面的这些函数...效率都是会有保证的...
我们自己写最多是和那里面的效率一样.....
czbever 2008-11-21
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 jamesfoo 的回复:]
我问了一位做硬件的朋友,他的解释是从硬件来考虑的。

如果是在32位机上(寄存器和数据总线皆为32位),CPU每次对内存的操作最多也就是32位,两者的效率可能是一样的。

如果是在64位机上(寄存器和数据总线皆为64位),则需要了解memset函数是否会64位操作,如果会,则memset的效率会更高一些
[/Quote]


顶一下这位高人
ghostwcy 2008-11-21
  • 打赏
  • 举报
回复
在操作的内存很大时,应该memset快
一般CPU都有一条指令,该指令可以操作一块内存(大小一般在一个page)
memset实现时,一般都使用该指令,执行的指令个数变低,减少从内存读取指令的时间,减少跳转的次数
而正如9楼说的,将内存快赋值,两者间的速度相差不大,至少memset不比手动赋值慢
使用memset的不足在于函数调用的开销,但这开销是固定的
终上,如果内存很大,memset会明显比手动赋值快
bitxinhai 2008-11-21
  • 打赏
  • 举报
回复
memset好,系统对memset的操作做了
优化,效率会高一些!!!
WingForce 2008-11-21
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 jamesfoo 的回复:]
我问了一位做硬件的朋友,他的解释是从硬件来考虑的。

如果是在32位机上(寄存器和数据总线皆为32位),CPU每次对内存的操作最多也就是32位,两者的效率可能是一样的。

如果是在64位机上(寄存器和数据总线皆为64位),则需要了解memset函数是否会64位操作,如果会,则memset的效率会更高一些
[/Quote]
memset的多数实现版本都会利用机器字长,而且会正确处理字长边界的问题
jamesfoo 2008-11-21
  • 打赏
  • 举报
回复
我问了一位做硬件的朋友,他的解释是从硬件来考虑的。

如果是在32位机上(寄存器和数据总线皆为32位),CPU每次对内存的操作最多也就是32位,两者的效率可能是一样的。

如果是在64位机上(寄存器和数据总线皆为64位),则需要了解memset函数是否会64位操作,如果会,则memset的效率会更高一些
clarence_songyifei 2008-11-21
  • 打赏
  • 举报
回复
看看 C专家编程 151页

用的是memcpy和for循环直接赋值的比较。memcpy要快很多,解释的原因是memcpy做了一些优化从而是Cache命中率提高。
所以,一般来说,C库函数还是有些优化会比自己的代码更快。除非你能很了解CPU,内存等等的特性,也许写出的代码比库函数更好也是很正常的。
iambic 2008-11-20
  • 打赏
  • 举报
回复
正确性更重要。
考虑当sizeof(int)为4和8的情况。
就呆在云上 2008-11-20
  • 打赏
  • 举报
回复
先给个源代码我实现的:
int main() 
{
int a[1024];
for(int i=0;i <1024;i++)
a[i]=0x80808080;
memset(a,0x80,1024*sizeof(int));
return 0;
}

再看汇编吧:
	for(int i=0;i <1024;i++) 
004115C2 mov dword ptr [i],0
004115CC jmp main+3Dh (4115DDh)
004115CE mov eax,dword ptr [i]
004115D4 add eax,1
004115D7 mov dword ptr [i],eax
004115DD cmp dword ptr [i],400h
004115E7 jge main+5Ch (4115FCh)
a[i]=0x80808080;
004115E9 mov eax,dword ptr [i]
004115EF mov dword ptr a[eax*4],80808080h
004115FA jmp main+2Eh (4115CEh)
memset(a,0x80,1024*sizeof(int));
004115FC push 1000h
00411601 push 80h
00411606 lea eax,[a]
0041160C push eax
0041160D call @ILT+720(_memset) (4112D5h)
00411612 add esp,0Ch


明显后面的慢些哦,函数调用,虽然我们无法得到memset的具体执行方式,但是我估计,应该也是想for循环一样有这么个过程
那么这么一来后面的就要慢很多了

其实可以这样撒
你用测量时间clock的方式比较一下做一万次这个动作的时候对比!
cyj626 2008-11-20
  • 打赏
  • 举报
回复
最好看汇编
lbh2001 2008-11-20
  • 打赏
  • 举报
回复
你确定找到的是库的源码吗,其他人写的不算
很明显,for循环操作四个字节后要判断,而memset则不需要,当然要快,数组越大,快越多
dingyin44 2008-11-20
  • 打赏
  • 举报
回复
memset(a, 0x80808080, 1024)
这个高点
jamesfoo 2008-11-20
  • 打赏
  • 举报
回复
我在网上找到的memset代码,其实现类似与第一种方法,不像是1L说的块操作
WingForce 2008-11-20
  • 打赏
  • 举报
回复
比较这2段代码效率没有实际意义
lbh2001 2008-11-20
  • 打赏
  • 举报
回复
一般来说memset的效率更高,是块操作

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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