bzero 实现

发布于 2022-10-15 09:27:09 字数 5427 浏览 17 评论 0

有兴趣的可以跑跑看         linux tcp/ip

  1. #include<stdio.h>
  2. #define op_t unsigned long int
  3. #define opsiz (sizeof(op_t))
  4. typedef unsigned char byte;
  5. void bzero(void*,size_t);
  6. int main()
  7. {
  8.         int ans[100];
  9.         int i,j;
  10.         int *p=ans;
  11.         for(i=0;i<100;i++)
  12.         {
  13.                 ans[i]=i+1;
  14.         }
  15.         bzero(p,80*sizeof(int));
  16.         for(j=0;j<100;j++)
  17.         {
  18.                 printf("%d ",ans[j]);
  19.                 if((j+1)%20 == 0)
  20.                         printf("\n");
  21.         }
  22. }
  23. void bzero(void *s,size_t len)  //把s的前 len 字节设为 0
  24. {
  25.         long int dstp=(long int)s; // 指向数据存储的地址,(地址)
  26.         const op_t zero = 0;
  27.         if(len>=8)//若小于8个字节 就一个一个字节的置0, 否则,先对齐地址。
  28.         {
  29.                 size_t xlen;
  30.                 while(dstp % opsiz !=0)  //这种情况是 地址没有对齐到 4个字节。那就先一个一个字节的置0.
  31.                 {
  32.                         ((byte *) dstp)[0]=0;
  33.                         dstp +=1;
  34.                         len-=1;
  35.                 }
  36.                 xlen=len/(opsiz * 8); //xlen是看看剩下有 多少个 32字节
  37.                 while(xlen!=0) //每次循环 置0 32个字节 8*op_t 把循环展开,提高了效率。
  38.                 {
  39.                         ((op_t *)dstp)[0]=zero;
  40.                         ((op_t *)dstp)[1]=zero;
  41.                         ((op_t *)dstp)[2]=zero;
  42.                         ((op_t *)dstp)[3]=zero;
  43.                         ((op_t *)dstp)[4]=zero;
  44.                         ((op_t *)dstp)[5]=zero;
  45.                         ((op_t *)dstp)[6]=zero;
  46.                         ((op_t *)dstp)[7]=zero;
  47.                         dstp+= 8* opsiz;
  48.                         xlen-=1;
  49.                 }
  50.                 len %= opsiz * 8; //剩余没有凑成 32个字节的数据
  51.                 xlen = len/ opsiz; //那就 每次循环置位 4个字节
  52.                 while(xlen!=0)
  53.                 {
  54.                         ((op_t *)dstp)[0]=zero;
  55.                         dstp +=opsiz;
  56.                         xlen -= 1;
  57.                 }
  58.                 len%=opsiz;
  59.         }
  60.         while(len!=0)//剩下的不够4个字节的,就一个字节一个字节 置0.
  61.         {
  62.                 ((byte *)dstp)[0]=zero;
  63.                 dstp += 1;
  64.                 len -= 1;
  65.         }
  66. }

复制代码之所以这样赋值是考虑了函数的通用性,不论是char(一个字节),int(4个字节),还是double(8个字节/32位系统),在64位系统上都可以通用,也就是 保证了void *s 的泛型。
每次赋值都尽可能利用cpu指令周期,高效的拷贝。这个方法 是达夫对于连续拷贝内容的精巧改进,也叫达夫设备。 可以通过switch结构和循环结构混合提高执行效率,
原因是在汇编代码中,对于case值连续的switch分支,往往被实现为一个跳转表,因此更加高效。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文