免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2972 | 回复: 15
打印 上一主题 下一主题

ACE 一句话代码赏析 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-01-19 21:49 |只看该作者 |倒序浏览
ACE_align_binary这个宏以前没怎么仔细看过,今天细看了一下不由得又对ACE的大牛们佩服不已了一番,
了解这个宏的朋友就不用浪费时间了,说得有什么不对的请大家指正.

原代码:
#define ACE_align_binary(ptr, alignment) \
    ((ptr + ((ptrdiff_t)((alignment)-1))) & (~((ptrdiff_t)((alignment)-1))))

先说问题:
一个字节流例如:101010101010101000011111111100111111100111110011010101011011
我们的类为了序列化的通用性,以某一字节对齐(以下讨论均假设为8位对齐),就是说
每8位or8×x位便是一个有意义的数据,比如 第0-7是一个有意义的单位,而1-9就没有意义,
也就是说读取数据必须从8的整数倍处开始,而数据指针可能由于种种原因可能不在8的整数倍上,
如何保证读取数据时一定是从8的整数位置开始的。

比如:
指针位于 0,则读取位置应该是0
指针位于 1,则读取位置应该是8
指针位于 2,则读取位置应该是8
...          ...
指针位于 8,则读取位置应该是8
指针位于 9,则读取位置应该是16
指针位于 10,则读取位置应该是16

总结一下:
if (ptr==8n)ptr=ptr;

if(8n<ptr<8(n+1))ptr=8(n+1);

为了便于理解,在此写一个同样功能的函数(见笑)
char * my_align_binary(char * ptr,int alignment)
{
        if(ptr%8==0)return ptr;
        else        return ptr+alignment - (ptr+alignment)%8
}

这个与原版的相比,差的实在是太远了
#define ACE_align_binary(ptr, alignment) \
    ((ptr + ((ptrdiff_t)((alignment)-1))) & (~((ptrdiff_t)((alignment)-1))))

这段代码的注释很详尽,但是做为一个chinese,我的e文也不怎么好,开始确实没怎么看懂,正所谓数读百遍,其义自见,一看就懂的朋友就不用在这里浪费时间了,看懂后不由得又对ACE的大牛们敬佩不已一番。

我们看一下这句话是怎么达到目的的,理解的关键在于 & (~((ptrdiff_t)((alignment)-1)))
注意alignment是2的n次方,二进制形式是..00..010..00..
设value=(ptr + ((ptrdiff_t)((alignment)-1)))
& (~((ptrdiff_t)((alignment)-1)))就是直接将value后面的尾数丢掉,假设alignment等于8,~(alignment)-1)意即
将value的后三位去掉,关键就在这里,8 二进制就是 1000 ,将后三位去掉,就是去掉模8的零头,变成8的整数倍
再看开始为什么要前进(alignment)-1步呢,
列举一下:

if (ptr==8n)前进(8-1)步然后去掉零头,还是ptr;
if(8n<ptr<8(n+1))前进(8-1)步,必然导致 8(n+1)<=ptr<8(n+2),然后去掉零头,得到8(n+1);

done!

看出来了吧,ACE_align_binary通过简单的加和与运算,完成的的确非常漂亮

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2007-01-19 21:57 |只看该作者
这个取整的宏以前就讨论过。
不过还是赞扬一下楼主乐于分享的精神。

论坛徽章:
0
3 [报告]
发表于 2007-01-19 22:01 |只看该作者
====

是的,作者必然是一个数学学得好的人。

====

论坛徽章:
0
4 [报告]
发表于 2007-01-19 22:36 |只看该作者
呵呵,长见识了~这些牛人们都是神一般的存在着,努力向他们学习...

论坛徽章:
0
5 [报告]
发表于 2007-01-19 23:19 |只看该作者
我一般都是用 (offset + 7) & (~7) 原理应该一样
gcc中栈对齐也是类似算法

论坛徽章:
0
6 [报告]
发表于 2007-01-19 23:52 |只看该作者
不懂ACE
问几个疑惑
1,ptr是不是应该指的是数组的下标?不应该是指针吧
2,被这个宏忽略的数据不处理了吗?似乎是从头头上开始忽略,处理了后面的前面的零头不要了?

论坛徽章:
0
7 [报告]
发表于 2007-01-20 00:45 |只看该作者
原帖由 bleem1998 于 2007-1-19 23:52 发表
不懂ACE
问几个疑惑
1,ptr是不是应该指的是数组的下标?不应该是指针吧
2,被这个宏忽略的数据不处理了吗?似乎是从头头上开始忽略,处理了后面的前面的零头不要了?

1。指针、下标都可以,这里字节流可以看成字符数组理解
2。数据是不是被忽略,完全是由参数ptr和alignment决定的。正如问题所描述的那样,是因为有时需要数据的起始点满足某特定要求(如这儿的对齐)

论坛徽章:
0
8 [报告]
发表于 2007-01-20 01:00 |只看该作者
这种宏很多库里都有,实现大同小异

论坛徽章:
0
9 [报告]
发表于 2007-01-20 01:54 |只看该作者
原帖由 tyc611 于 2007-1-20 00:45 发表

1。指针、下标都可以,这里字节流可以看成字符数组理解
2。数据是不是被忽略,完全是由参数ptr和alignment决定的。正如问题所描述的那样,是因为有时需要数据的起始点满足某特定要求(如这儿的对齐)


谢谢解答

论坛徽章:
0
10 [报告]
发表于 2007-01-20 11:15 |只看该作者
有个宏,好象是ace_return

#define ace_return(x,y)  return(y)

为什么要用x,替换后x就没了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP