蘑菇团购的问题解决了,但是却又引入了一个新的疑问:内存对齐(memory alignment)。
所谓内存对齐,就是将数据存放到一个是字的整数倍的地址指向的内存之中。处理器在执行指令去操作内存中的数据,这些数据通过地址来获取。不论什么数据都有一定的大小,当一个数据所在的地址和它的大小对齐的时候,就说这个数据自然对齐了(naturally aligned),否则就是没对齐。
怎么理解数据的地址和它的大小对齐这句话呢?例如有一个地址a,它是n的整数倍,并且这个n是2的幂,这时候我们就可以说a和n个字节对齐了。举个栗子:当 a = 0x00000008,n = 4,22= 4 的时候,就说地址a和4字节对齐了[2]。
套用到数据的地址和它的大小对齐这句话,例如一个long变量,它占用4个字节,也就是他的大小是4字节,如果这个变量的地址为0x00000004、0x00000008等,那么这个变量就和4字节对齐了,而如果它的地址是0x00000006之类的,那么它就没对齐。
当存取一个地址对齐了它数数据大小的数据结构的时候,就说这是一次对齐存取。上面的例子说的是基本数据类型,当一个复杂的数据结构中的所有成员都自然对齐了,我们就说这个数据结构对齐了,为了能让复杂数据结构对齐,编译器一般会对数据结构做一些填充,使得它的成员都能对齐。
很多时候,我们是不需要关注内存对齐的问题的,因为处编译器已经自动为数据进行对齐:对于基本数据类型,编译器会给他们分配一个是他们大小n被的地址;对于组合类型数据结构,编译器会在成员函数中填充一些字节使得每个成员都自然对齐[5]。
这个虽然看上去整个结构体只占用了8个字节,但是世界上因为编译器做了填充使得结构体的成员都能对齐,这个结构体实际上占据了12个字节。编译器填充完的结构体如下:
但是有些时候,出于一些特殊的需求,需要人工干预编译器的对齐工作。例如,虽然一个int类型的数据在某些机器上只占了四个字节,但是你却希望它能够按照16个字节对齐,这个时候你就可以使用int x __attribute__ ((aligned (16))) = 0;来指导编译器按照你想要你的对齐方式进行对齐。
了解了对齐,处理让我们知道怎么使用__attribute__ ((aligned ))这个命令意外,有时候也可以指导我们怎么样安排一个数据结构使得空间利用率变高,例如吧上面结构体中的成员的顺序改成下面这样,这个结构体就从原来的占用12个字节变成占用8个字节,节省了30%的空间。如果这个结构体在内存中存在成百上千个,省出来的空间就很客观了。这样不仅能让我们的数据对齐,同时还实现了数据的紧凑。
通过一段代码来描述内存对齐的现象。 上述代码打印出来的结果为:24,16 为什么相同的结构体,只是交换了变量 ab...
什么是内存对齐 理论上计算机对于任何变量的访问都可以从任意位置开始,然而实际上系统会对这些变量的存放地址有限制,通...
查询内网中关于内存对齐的资料发现,它们往往只谈论一个层面的问题,而不涉及或稍微涉及更高或更低层面的问题;而这对于喜...
家长要从细节中去发现她的成长轨迹,以及现在的心理状态。家长需要在细节中体现关爱,并理解和尊重孩子,与他共同成长。这...
心懒懒的,就想找个人聊聊。可是,聊什么呢?还有共同语言吗?就像是两个的世界的人。几句话心里的湖水就见底了,接下来就...
刘润5分钟 番茄工作法 小番茄:工作25分钟,休息5分钟 大番茄:工作50分钟,休息10分钟 练习工作的专注力 当...
问:想必微信公众号运营者都很清楚,企业服务号如果不发消息,那么粉丝稳步增长,只要一发消息,那么当日粉丝会疯狂的下降...
前天回京的机上广播里说:北京地表温度23度。 飞机上大家不约而同的啊一声,这太意外了,然后大家纷纷表示不信,猜测是...
|