字节对齐学习

来源:互联网 发布:手机看淘宝实名认证了 编辑:程序博客网 时间:2024/06/07 22:49

基本概念

字长

CPU在单位时间内(同一时间)能一次处理的二进制数的位数叫字长。需要注意一点,CPU的字长和具体的机器相关,比如对于32位系统,表明当前CPU的字长是32位,即CPU可以同时处理32位数据。

CPU字(Word)和比特(Bit)、字节(Byte)都是计算机保存信息的单位,只不过他们的量级不一样。为什么CPU字这个东西很重要,因为这牵扯到内存对其的问题。

对于大多数CPU来说,CPU字长的整数倍操作起来更快,因此对于这些成员加起来如果不够这个整数倍,有可能编译器会插入多余的内容凑足这个整数倍,此外,有时候相邻的成员之间也有可能因为这个目的被插入空白,这个叫做“补齐”(padding)。记住一点,内存对其就是要凑够一个CPU字,这样操作起来更快。

什么是字节对齐?为什么字节对齐?

来自《深入理解计算机系统》

Many computer systems place restrictions on the allowable addresses for the primitive data types, requiring that the address for some type of object must be a multiple of some value K (typically 2, 4, or 8).
简言之,系统要求对象的地址必须是自身类型的整数倍。

原因在于:

Such alignment restrictions simplify the design of the hardware forming the interface between the processor and the memory system.
这种设计可以简化(处理器和存储系统之间接口)硬件设计。

例子:

For example, suppose a processor always fetches 8 bytes from memory with an address that must be a multiple of 8. If we can guarantee that any double will be aligned to have its address be a multiple of 8, then the value can be read or written with a single memory operation. Otherwise, we may need to perform two memory accesses, since the object might be split across two 8-byte memory blocks.
假设对于一个32位机器,处理器每次去内存取4个字节,并且变量的地址都是4的整数倍。这样的话,每次一次访存就可以取出一个int变量。如果,不采用字节对齐,那么对于一个int变量,存放它的地址可以不是4的整数倍,这回导致一个int变量存储在2个4-byte memery blocks当中,此时取出它就需要访问存储器两次。

一个例子

#include <stdio.h>struct A {    char a; // 1 byte    int b;  // 4 byte    char c; // 1 byte    short d;// 2 byte};int main( void ){    printf( "%ld\n", sizeof(struct A) );    struct A obj;    printf( "%#x\n", &obj );    printf( "%#x\n", &(obj.a) );    printf( "%#x\n", &(obj.b) );    printf( "%#x\n", &(obj.c) );    printf( "%#x\n", &(obj.d) );    return 0;}/*120x4b341bf00x4b341bf00x4b341bf40x4b341bf80x4b341bfa*/

正常情况下,这个类型应该占8 bytes.但是结果是12.

结构体字节对齐规则

  1. 以成员中最大的数据类型为步长分配内存块给结构体
  2. 每个成员存储的起始地址必须是自身类型的整数倍。

a: 1000
b: 1111
c,d: 1010

这个图怎么看,最大的类型是Int,4bytes.所以,每次内存分配的步长都是4bytes. c,d都在一个4bytes的原因是,1.他们大小够,可以存放在这里。所以,不发生内存分配,其次,地址必须是类型的倍数。short是2bytes,所以,不能紧跟着c进行存放。其实对于b是一样的道理,内存不够进行分配,但是分配之后不能存储在a的后面,因为规则2.

0 0
原创粉丝点击