zqurgy

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

内存对齐

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)

posted on   ZqurGy  阅读(321)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示