zoukankan      html  css  js  c++  java
  • 基础概念——字节对齐

    为什么要字节对齐?

      字节对齐实际上是牺牲空间换取时间的行为;

      为了解决CPU访问数据的效率问题;CPU访问数据都会读取固定字长的数据,例如32位CPU,一次性会读取32bit的数据;

      例如:

      第一次会读取0x0000, 0x0001, 0x0002, 0x0003 这四个地址空间内的数据(每个地址存着1字节的数据),总共4字节,即32位的数据;

      第二次会读取0x0004, 0x0005, 0x0006, 0x0007 这四个地址空间内的数据;

      假设有一个变量的大小为4个字节;

      如果存放在0x0002, 0x0003, 0x0004, 0x0005这四个地址空间中,那么CPU访问该变量时,就需要读两次;

      如果存放在0x0004, 0x0005, 0x0006, 0x0007这四个地址空间中,那么CPU访问该变量时,就需要读一次;

      也就是说变量的起始地址要天然能被字长整除;0x0004%4=0; 换种说法就是字节对齐

      一些平台读取数据的地址都是从特定的地址开始存取的,例如从偶地址开始存取;

      如果数据存放的起始地址跟读写起始地址一致,就会有效减少访问次数,从而节约时间,提升效率;

    对齐的理解:一个数据的起始地址能够被其长度整除;或者说起始地址是其长度的整数倍。

    起始地址要符合自然边界条件;这个条件是指其起始地址值和数据长度的关系;整数倍关系;start_addr % data_len = 0

     
    结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。
    指定对齐值:#pragma pack (value)时的指定对齐值value。
    数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。

    默认对齐值:结构体中每个数据成员及结构体本身都有默认对齐值,记为defaultLen;
    指定对齐值:代码中指定的对齐值,记为packLen;

    成员偏移量:每个成员相对于结构体起始位置的长度,记为offset;
    成员长度:结构体中每个数据成员的长度(注结构体成员为补齐之后的长度),记为memberLen。

    对齐规则: offset % vaildLen = 0,其中vaildLen为有效对齐值,vaildLen = min(packLen, defaultLen);
    填充规则: 如成员变量不遵守对齐规则,则需要对其补齐;在其前面填充一些字节保证该成员对齐。需填充的字节数记为pad

    在Linux中2字节数据类型(例如short)的地址必须是2的倍数,而较大的数据类型(例如int,int *,float和double)的地址必须是4的倍数。
    也就是说Linux下要么2字节对齐,要么4字节对齐,没有其他格式的对齐。



    参考链接:

    C语言字节对齐:https://blog.csdn.net/21aspnet/article/details/6729724

  • 相关阅读:
    hdu 1381 Crazy Search
    hdu 5131 Song Jiang's rank list
    poj 2251 Dungeon Master
    hdu 4941 Magical Forest
    hdu 1728 逃离迷宫
    hdu 2612 Find a way
    hdu 3288 Resource Allocation
    hdu 1272 小希的迷宫
    hdu 5224 Tom and paper
    hdu 5104 Primes Problem
  • 原文地址:https://www.cnblogs.com/grooovvve/p/14158927.html
Copyright © 2011-2022 走看看