memset的指针用long int是因为那个时候C99还没出来吗?
时间:2010-08-02
来源:互联网
还是说这么可以提高效率?
作者: yylogo 发布时间: 2010-08-02
作者: hellioncu 发布时间: 2010-08-02
啥? void*?
你是说函数原型是long int? 还是说copy的时候用long int?
作者: OwnWaterloo 发布时间: 2010-08-02
作者: daybreakcx 发布时间: 2010-08-02
下面是代码,里面的注释是我写的,我把原来的注释删了,到时候发表到博客里面去。
http://zqynux.blog.163.com/
- void *memset(void *dstpp, int c, size_t len)
- {
- long int dstp = (long int) dstpp;
- /* 正在翻阅为什么用long int 而不是void * */
-
- if (len >= 8) {
- size_t xlen;
- op_t cccc;
- /* 关于op_t这个类型, 在memcmp中有定义
- # define op_t unsigned long int
- # define OPSIZ (sizeof(op_t)) */
-
-
- /* 每次操作对多个字节进行赋值 */
- cccc = (unsigned char) c;
- cccc |= cccc << 8;
- cccc |= cccc << 16;
- if (OPSIZ > 4) /* 如果是64位的机子的话, 还可以再多用4个字节 */
- cccc |= (cccc << 16) << 16;
-
- while (dstp % OPSIZ != 0) { /* 让内存地址对齐地址总线的长度, 以
- 得到最高的效率! */
- ((byte *) dstp)[0] = c;
- dstp += 1;
- len -= 1;
- }
-
- xlen = len / (OPSIZ * 8); /* 每次赋值8个,也就是说如果在32位的机子上的话
- 每次赋值4*8=32个字节,64位的机子就是64字节 */
- while (xlen > 0) {
- ((op_t *) dstp)[0] = cccc;
- ((op_t *) dstp)[1] = cccc;
- ((op_t *) dstp)[2] = cccc;
- ((op_t *) dstp)[3] = cccc;
- ((op_t *) dstp)[4] = cccc;
- ((op_t *) dstp)[5] = cccc;
- ((op_t *) dstp)[6] = cccc;
- ((op_t *) dstp)[7] = cccc;
- dstp += 8 * OPSIZ;
- xlen -= 1;
- }
- len %= OPSIZ * 8; /* 得到余下的未赋值的字节数,一定小于32 */
-
- xlen = len / OPSIZ; /* 每次赋值1个, 32位机子4个字节一次, 64位8个 */
- while (xlen > 0) {
- ((op_t *) dstp)[0] = cccc;
- dstp += OPSIZ;
- xlen -= 1;
- }
- len %= OPSIZ; /* 得到余下的未赋值的字节书,一定小于4 */
- }
-
- while (len > 0) { /* 最后剩下的几个字节单独赋值 */
- ((byte *) dstp)[0] = c;
- dstp += 1;
- len -= 1;
- }
-
- return dstpp;
- }
作者: yylogo 发布时间: 2010-08-02
作者: yylogo 发布时间: 2010-08-02
一次性复制一个机器字相比将机器字拆分成若干个byte来说, 确实效率会高。
作者: OwnWaterloo 发布时间: 2010-08-02
我是问那个变量为什么不用void *还是long int,是不是其中还有什么奥妙。
作者: yylogo 发布时间: 2010-08-02
void*不能增。
我奇怪的是为什么不用char*。
作者: OwnWaterloo 发布时间: 2010-08-02
哦,, 我错了...
高手就是高手..
作者: yylogo 发布时间: 2010-08-02
http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc/string/memset.c?rev=1.9
作者: langue 发布时间: 2010-08-02
回复 langue
哦, 就是这么一回事啊.. 我以为有什么玄机呢.
不过FreeBSD的这个好难理解..
作者: yylogo 发布时间: 2010-08-02
你blog中那个泡泡兵的表情笑死我了……
推荐放弃网易blog, 改用is-programmer或者cppblog……
作者: OwnWaterloo 发布时间: 2010-08-02
回复 OwnWaterloo
额,, 那个is-programmer, cppblog可以搬家吧?
一篇一篇复制太麻烦了, 而且网易里面还有一些OIer, 不知道is-programmer里面有没有
作者: yylogo 发布时间: 2010-08-02

作者: daybreakcx 发布时间: 2010-08-02
额,,, 有点近似无语了,, FreeBSD 这一个东西实现俩函数?
我再琢磨下
作者: yylogo 发布时间: 2010-08-02
仔细一看…… 文章挺多……
而且, 你才15岁啊? 前途无量……
搬家么, 不一定需要搬吧? 转过去就是了。
网易不是专为程序员打造的blog, 我记得连回复订阅的功能都没有。
cppblog人气高。 你在首页上发一贴, 一天的流量就比你现在的多了。
is-programmer的功能很齐全, 但好像没cppblog人这么多。
作者: OwnWaterloo 发布时间: 2010-08-02
对对。
搞oi, 总要写点公式吧? 公式复杂了总要用tex吧?
is-programmer就是我搜tex online时搜到的……
作者: OwnWaterloo 发布时间: 2010-08-02
恩, 这个我再琢磨下..
作者: yylogo 发布时间: 2010-08-02
问问(length & wmask) 是什么意思? wmask在32位的机子就是3吧?
那如果length 在后两位都是零怎么办?
作者: yylogo 发布时间: 2010-08-02
哦,, 我知道了, 这也是地址对齐的功能
作者: yylogo 发布时间: 2010-08-02
额, 前途无量啊.

作者: yylogo 发布时间: 2010-08-02
是的,题外话是这件事可以追溯到较早以前,大概 17 年前,也就是在 4.4BSD 发布的时候,bzero.c 的内容合并到了 memset.c,这一个文件就同时实现了 bzero(3) 和 memset(3)。
作者: langue 发布时间: 2010-08-02
OI没要求OS吧? 先抓OI, linux等拿到奖后再慢慢玩。
好像现在不加分了?
作者: OwnWaterloo 发布时间: 2010-08-02
那我冒昧的问句, 这不同时只能实现一个函数?
作者: yylogo 发布时间: 2010-08-02
Yes, you are right!!!
作者: yylogo 发布时间: 2010-08-02
gcc -c -DBZERO memset.c -o bzero.o
gcc memset.o bzero.o
...
- void* memset(void* dst, int val, size_t len) { ... }
- void bzero(void* dst, size_t len) { memset(dst, 0, len); }
如果可以优化到一样, 那bsd的写法就碍眼了。
作者: OwnWaterloo 发布时间: 2010-08-02
确实不太公平…… 其他竞赛都可以加, 凭什么OI不行……
作者: OwnWaterloo 发布时间: 2010-08-02
哦, 编译两次, 第一次加宏bezro, 第二次不要..
作者: yylogo 发布时间: 2010-08-02
确实同时只实现一个,在编译时根据参数的不同来做一定的调整。参考 src/lib/string/Makefile.inc
bzero.o: memset.c
${CC} -DBZERO ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET}
@${LD} -x -r ${.TARGET}
@mv a.out ${.TARGET}
作者: langue 发布时间: 2010-08-02
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28