免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: OwnWaterloo
打印 上一主题 下一主题

memcpy vs strcpy vs strlen [复制链接]

论坛徽章:
0
21 [报告]
发表于 2010-08-20 17:35 |只看该作者
dst=17, src=65, 那么首先复制1个byte, 然后按上面处理。
dst=18, src=66, 那么前2个byte可以一次复制2byte或者复制2次1byte, 看哪个快, 然后按上面处理。
]

在这,是不是应该首先复制 WORD_LEN - 1 个byte?

论坛徽章:
0
22 [报告]
发表于 2010-08-21 11:04 |只看该作者
回复 1# OwnWaterloo


    收藏一下。。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
23 [报告]
发表于 2010-08-21 12:21 |只看该作者
回复 21# sorrento

分组的最长长度 L 应该是 abs(src-dst)中的所有2因子的积。
但实际上, 太长了也相当于是手工解循环, 而不是重复利用cpu字长了, 可以选一个比它小的l来复制。
src(以及dst)对l的余数就是前面的padding。

论坛徽章:
0
24 [报告]
发表于 2010-08-21 14:42 |只看该作者
本帖最后由 huxk 于 2010-08-21 14:43 编辑

滑鐵盧 這個搞法解釋一下。謝謝。
  1. /*

  2. #if (NGX_MEMCPY_LIMIT)

  3. void *ngx_memcpy(void *dst, void *src, size_t n);
  4. #define ngx_cpymem(dst, src, n)   ((u_char *) ngx_memcpy(dst, src, n)) + (n)

  5. #else
  6. * gcc3, msvc, and icc7 compile memcpy() to the inline "rep movs".
  7. * gcc3 compiles memcpy(d, s, 4) to the inline "mov"es.
  8. * icc8 compile memcpy(d, s, 4) to the inline "mov"es or XMM moves.
  9. */
  10. #define ngx_memcpy(dst, src, n)   (void) memcpy(dst, src, n)
  11. #define ngx_cpymem(dst, src, n)   ((u_char *) memcpy(dst, src, n)) + (n)

  12. #endif


  13. #if ( __INTEL_COMPILER >= 800 )

  14. /*
  15. * the simple inline cycle copies the variable length strings up to 16
  16. * bytes faster than icc8 autodetecting _intel_fast_memcpy()
  17. */

  18. static ngx_inline u_char *
  19. ngx_copy(u_char *dst, u_char *src, size_t len)
  20. {
  21.         if (len < 17)
  22.         {

  23.                 while (len)
  24.                 {
  25.                         *dst++ = *src++;
  26.                         len--;
  27.                 }

  28.                 return dst;

  29.         }
  30.         else
  31.         {
  32.                 return ngx_cpymem(dst, src, len);
  33.         }
  34. }
复制代码

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
25 [报告]
发表于 2010-08-22 08:08 |只看该作者
回复 24# huxk

有两个条件编译: NGX_MEMCPY_LIMIT和__INTEL_COMPILER >= 800

__INTEL_COMPILER好像没帖完……


无论NGX_MEMCPY_LIMIT是否为真, 后续代码都会得到两个函数(或者宏):
ngx_memcpy和memcpy一样, 不过src不是void const*。
ngx_cpymem和memcpy类似, 返回值是dst的末尾而不是起始。

如果NGX_MEMCPY_LIMIT为假。
ngx_memcpy是被定义为memcpy, ngx_cpymem使用memcpy完成。
理由应该就是注释说的: 3种编译器对memcpy都可以产生很好的代码。

否则就是用真正的ngx_memcpy, 应该是其他地方定义的一个函数。
ngx_cpymem使用ngx_memcpy完成。


其实短小一些的话, 这样就可以了:

  1. #if (NGX_MEMCPY_LIMIT)
  2. void *ngx_memcpy(void *dst, void *src, size_t n);
  3. #else
  4. // 这个宏定义的返回值和真正函数不一致
  5. #define ngx_memcpy(dst, src, n)   (void) memcpy(dst, src, n)
  6. #endif

  7. #define ngx_cpymem(dst, src, n)   ((u_char *) ngx_memcpy(dst, src, n)) + (n)
复制代码

论坛徽章:
0
26 [报告]
发表于 2010-09-10 21:23 |只看该作者
本帖最后由 alexhuang2010 于 2010-09-10 21:36 编辑

回复 3. 检测cache情况

有些malloc(甚至calloc)的实现在实际访问内存前, 是不会分配物理内存的。
所以, 对先被测试的函数来说总是不公平的, 它会引发多得多的页错误。
比较的不是memcpy和strcpy的比较, 而是它们和页置换算法+memcpy的比较。

可以考虑将相同的动作执行连续执行2(多)次, 取后一次(第2次之后的综合)结果。 OwnWaterloo



“有些malloc(甚至calloc)的实现在实际访问内存前, 是不会分配物理内存的。”
请问楼主,这个说法的依据是什么?? malloc基于slab算法来分配内存,而slab算法基于buddy算法,虚拟页表只是一个present标记它是否映射了物理页,缺页换页就是将该要访问的地址,也就是程序中链接地址所在的一页代码换到物理页中,然后将原页表映射到该物理页中。如果malloc分配的内存是在缺页换页发生时创建的,你觉得换页的异常处理程序如何做上述操作。

而且你也提到cache了,为什么你不觉得两次相同动作执行速度不一样不是因为第一次执行的时候CPU访问DDR而第二次执行的时候CPU访问cache造成的呢。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
27 [报告]
发表于 2010-09-11 09:08 |只看该作者
回复 26# alexhuang2010

>> malloc基于slab算法来分配内存,而slab算法基于buddy算法,虚拟页表只是一个present标记它是否映射了物理页

你是不是觉得世界上所有的内存管理代码都是抄袭的linux kernel的?

论坛徽章:
0
28 [报告]
发表于 2010-09-11 11:55 |只看该作者
回复 27# OwnWaterloo


      你还是没有回答我的问题,依据在哪??哪个libc版本的malloc实现??malloc是自己实现??

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
29 [报告]
发表于 2010-09-11 14:07 |只看该作者
回复 28# alexhuang2010

如果你有windows系统, 你可以试一试:

1. 用malloc(甚至calloc) 分配足够大块的内存
2. 使用GetProcessMemoryInfo查看内存使用

其中WorkingSetSize是实际分配的物理内存, PagefileUsage页文件占用。
(分别对应着 VirtualAlloc( ... ,MEM_COMMIT, )  VirtualAlloc( ... , MEM_REVERSE, ... ) )


3. memset这些内存 (甚至可以巧妙一点, 只需要touch每个页中的某个字节)
4. 再次memset
5. 再次memset ...


你可能观察到的现象:
1. malloc后, 物理内存占用增加远少于需求的数量, 但页文件增加和需求数量相同。
2. 每触碰1页, 物理内存占用增加1页。
3. 第2次以及后面的memset的时间基本相同, 远小于第1次的时间


msvc的crt中的malloc, 使用的是windows api: HeapXXX, 这套机制是没有源代码的。
但上面的现象, 应该足够说明:
1. 一个好的malloc(甚至calloc)实现, 是可以做到利用OS提供的机制, 在物理页面没有被真正使用前, 不分配物理页面。
2. 一个推论就是文中说的, 分配后立马比较是不公平的, 至少应该touch一次。



如果你没有Windows系统, 而是linux, 那你也应该知道linux的机会主义分配策略。
http://stackoverflow.com/questio ... x-to-exhaust-memory

论坛徽章:
0
30 [报告]
发表于 2011-09-05 11:23 |只看该作者
回复 1# OwnWaterloo


    你是lw嘛? 风格好像啊{:3_189:}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP