字节对齐学习

基本概念

字长

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;
}
/*
12
0x4b341bf0
0x4b341bf0
0x4b341bf4
0x4b341bf8
0x4b341bfa
*/

正常情况下,这个类型应该占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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值