字节对齐头疼不已?(上)---通俗易懂理清字节对齐那些事儿

        博主想起刚接触字节对齐时被他支配,受他困扰,知道有字节对齐这么个事儿,但就说不出个所以然。特别是再看看编译器对结构体字节对齐规则的定义:

 编译器:结构体对齐规则:

 1) 数据类型自身的对齐值:char型数据自身对齐值为1字节,short型数据为2字节,int/float型为4字节,double型为8字节。

 2) 结构体的自身对齐值:其成员中自身对齐值最大的那个值。

 3) 指定对齐值:#pragma pack (value)时的指定对齐值value。默认是4。

 4) 数据成员、结构体的有效对齐值:自身对齐值和指定对齐值中较小者,即有效对齐值=min{自身对齐值,当前指定的pack值}。

        这都是些啥?对齐值?min{自身对齐值,当前指定的pack值}? #pragma ?看过了对齐规则感觉没看过对齐规则!

        有这个感觉就对了,笔者第一次接触时也一样!

        所以“字节对齐”是个啥?真的有这么困难?先不要着急,相信看完这篇文章回过头来看规则你就会恍然大悟,原来这TMD叫字节对齐啊!

为什么会有字节对齐

        字节对齐其实是在CPU在读写数据时发生的一次优化。为了方便理解,我们先看看没有字节对齐的情况下CPU在读写数据时都发生了什么?

        以32位CPU读取4bytes的数据为例:现在有一个变量A,A的长度为4bytes,A的存放起始地址为0x8001(为了方便举例只展示0x8000~0x08007段的数据)

未对齐的0x8000~0x08007段数据示意图

        那么很不幸,32位CPU想要读取A变量的值需要干四件事(注意虽然是四件事,但在底层只用两个读周期):

        1)获取0x8000~0x08003段的数据    

CPU获取前半段数据(读周期1)

        这里有个问题:为什么CPU不能从0x8001开始取数据?这样咱们不就可以直接获取变量A的数据了吗?

        这个问题很重要!因为我们32位计算机是4bytes(32bits)一取的,数据获取的粒度没有这么细,因此CPU在读写数据时为了提高效率都会规定为从特定地址开始操作,而不会从0x8001地址开始读取数据(虽然理论上可以)。简单理解的话就是32位CPU位提高效率都是从4的整数倍的地址开始读取数据的。

        2)获取变量A的前3个bytes数据

CPU获取前半段数据

        3)相同地获取0x08000004~0x08000007段的数据

CPU获取后半段数据(读周期2)

        4)获取变量A的最后1个byte数据

CPU获取后半段数据

        经历了四个步骤,咱们终于取到了变量A的数据,那如果我们采用了字节对齐的方式存储变量A呢?

        采用了字节对齐后的变量A的起始地址是能被4整除的,因此CPU一次读取就能获取A变量的数据了。

对齐后的0x8000~0x08007段数据示意图

        获取0x8000~0x8003段的数据,然后就OK啦

CPU获取A变量数据(读周期1)

        看,是不是方便多了,CPU每少执行一步,也就意味咱们软件的运行效率又高了一分啊!

        总的来说:

为什么会有字节对齐

        这一节咱们一起讨论了为什么会有字节对齐以及CPU读取数据的底层逻辑,下一节咱们一起看一看结构体字节是怎么对齐的

拓展思考:

        1、咱们讨论的情况是32位CPU在读写数据时会因为需要优化读写时间而进行字节对齐,那1位CPU(当然这种单bit的上古神器现在肯定是没有使用啦)会出现这种情况吗?64位CPU呢?

        2、咱们讨论的情况是在读写4bytes的数据时会因为需要优化读写时间而进行字节对齐,那读写1bytes数据会出现这种情况吗?读写8bytes的数据呢?

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值