bzero 实现
有兴趣的可以跑跑看 linux tcp/ip
- #include<stdio.h>
- #define op_t unsigned long int
- #define opsiz (sizeof(op_t))
- typedef unsigned char byte;
- void bzero(void*,size_t);
- int main()
- {
- int ans[100];
- int i,j;
- int *p=ans;
- for(i=0;i<100;i++)
- {
- ans[i]=i+1;
- }
- bzero(p,80*sizeof(int));
- for(j=0;j<100;j++)
- {
- printf("%d ",ans[j]);
- if((j+1)%20 == 0)
- printf("\n");
- }
- }
- void bzero(void *s,size_t len) //把s的前 len 字节设为 0
- {
- long int dstp=(long int)s; // 指向数据存储的地址,(地址)
- const op_t zero = 0;
- if(len>=8)//若小于8个字节 就一个一个字节的置0, 否则,先对齐地址。
- {
- size_t xlen;
- while(dstp % opsiz !=0) //这种情况是 地址没有对齐到 4个字节。那就先一个一个字节的置0.
- {
- ((byte *) dstp)[0]=0;
- dstp +=1;
- len-=1;
- }
- xlen=len/(opsiz * 8); //xlen是看看剩下有 多少个 32字节
- while(xlen!=0) //每次循环 置0 32个字节 8*op_t 把循环展开,提高了效率。
- {
- ((op_t *)dstp)[0]=zero;
- ((op_t *)dstp)[1]=zero;
- ((op_t *)dstp)[2]=zero;
- ((op_t *)dstp)[3]=zero;
- ((op_t *)dstp)[4]=zero;
- ((op_t *)dstp)[5]=zero;
- ((op_t *)dstp)[6]=zero;
- ((op_t *)dstp)[7]=zero;
- dstp+= 8* opsiz;
- xlen-=1;
- }
- len %= opsiz * 8; //剩余没有凑成 32个字节的数据
- xlen = len/ opsiz; //那就 每次循环置位 4个字节
- while(xlen!=0)
- {
- ((op_t *)dstp)[0]=zero;
- dstp +=opsiz;
- xlen -= 1;
- }
- len%=opsiz;
- }
- while(len!=0)//剩下的不够4个字节的,就一个字节一个字节 置0.
- {
- ((byte *)dstp)[0]=zero;
- dstp += 1;
- len -= 1;
- }
- }
复制代码之所以这样赋值是考虑了函数的通用性,不论是char(一个字节),int(4个字节),还是double(8个字节/32位系统),在64位系统上都可以通用,也就是 保证了void *s 的泛型。
每次赋值都尽可能利用cpu指令周期,高效的拷贝。这个方法 是达夫对于连续拷贝内容的精巧改进,也叫达夫设备。 可以通过switch结构和循环结构混合提高执行效率,
原因是在汇编代码中,对于case值连续的switch分支,往往被实现为一个跳转表,因此更加高效。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论