• 内存对齐


    1.内存对齐是什么?

    对结构体和类来说,让变量不是紧挨着存放,而是通过变量字节倍数的形式存放

    2.为什么会有内存对齐?

    • 增加cpu的访问数据的速度
      • 对于cpu来说,数据从内存中读到缓存中去,是通过偏移量(offset)进行读取,也就是常说的通过块来读取,而不是按照字节读取。
      • 读取非内存对齐的数据,会出现一次必须读取offset和offset+1两块数据这种情况,这需要为芯片增加额外的加法器( 为了得到offset+1 )。为了上述这种可能,而增加额外的设备,并且每一次的增加访问时间,显然是不明智的
      • 还有一点就是读了两次,读到缓存的位置上也需要两次,同样降低效率
    • 方便于不同机器、不同平台进行数据的准确读取

    3.内存对齐规则

    • 规则1:需要按照min(pack,sizeof(变量本身))的倍数进行选择开始位置

    • 规则2:整体按照min(pack,sizeof(字节数最大的变量))的倍数进行计算

    • 规则3:数组则按照本身是哪种类型变量进行计算,同样遵循规则1

    • 规则4:结构体中的结构体X,X内部遵循规则1计算大小,并且选择位置也遵循规则1

    • 注意:

      • 规则1和2,为主要原则,3和4作为拓展
      • sizeof得到所占字节数,pack为对齐模数
      • 查看对齐模数#pragma pack(show),编译时会显示

    4.案例

    运行环境:Microsoft Visual Studio Community 2022 (64 位) - Current版本 17.3.4
    对齐模数:#pragma pack(show) == 16

    • 案例1
    pack == 16
    struct A{
    char a; //0-3
    int b; //4-7
    double c;//8-15
    }; // 16/8 可除
    规则1:需要按照min(pack,sizeof(变量本身))的倍数进行选择开始位置
    规则2:整体按照min(pack,sizeof(字节数最大的变量))的倍数进行计算
    pack == 2
    struct B{
    char a; //0-2
    int b; //2-5
    double c;//6-13
    }; // 14/2 可除
    规则1:需要按照min(pack,sizeof(变量本身))的倍数进行选择开始位置
    规则2:整体按照min(pack,sizeof(字节数最大的变量))的倍数进行计算
    • 案例3
    pack == 16
    struct C{
    char a; //0-1
    short b[3];//2-7 --->the place
    int c; //8-15
    double d;//16-23
    }; // 24/8 可除
    规则3:数组则按照本身是哪种类型变量进行计算,同样遵循规则
    • 案例4
    pack == 16
    struct D{
    char a; //0-7
    struct C b;//8-31
    int c; //32-39
    double d;//40-47
    }; // 48/8 可除
    规则4:结构体中的结构体X,X内部遵循规则1计算大小,并且选择位置也遵循规则1
    pack == 2
    struct D{
    char a; //0-1
    struct B b;//2-15
    int c; //16-19
    double d;//20-7
    }; // 28/2 可除
    规则4:结构体中的结构体X,X内部遵循规则1计算大小,并且选择位置也遵循规则1

    5.其他的注意

    • 空类和空结构体的sizeof大小为1

    • 该环境下指针的大小为8个字节

    6.类与内存对齐

    待补充链接

    参考

    参考资料:浅谈CPU内存访问要求对齐的原因 – 仰望苍天思寰宇 (yangwang.hk)

  • 相关阅读:
    git的基本使用(一)
    ## 其它问题
    2022年安全员-C证考试模拟100题模拟考试平台操作
    路径分析—PostgreSQL+GeoServer+Openlayers(二)
    VHDL基础知识笔记(1)
    qt 6知识集
    【C语言】进制转换一般方法
    查看linux中的python版本(三种方法)
    tarfile.ReadError: not a gzip file
    Redis主从复制基础概念
  • 原文地址:https://www.cnblogs.com/zqurgy/p/17133404.html