字节对齐
字节对齐(Byte Alignment),也称为数据对齐(Data Alignment),是计算机系统中一种重要的内存管理概念。它指的是将数据在内存中的存放地址调整为特定数值(通常是其自身大小或系统字长的整数倍)的过程。
为什么要字节对齐?
主要原因与硬件效率密切相关:
- 硬件访问要求:
- 许多处理器(尤其是 RISC 架构如 ARM, MIPS, SPARC 和现代 x86)被设计为只能从某些特定的对齐地址(例如 2-byte, 4-byte, 8-byte 边界)高效地读取或写入数据。
- 例如,一个 32 位(4 字节)的整数,处理器可能要求其起始地址必须是 4 的倍数(如 0x0000, 0x0004, 0x0008, ...)。一个 64 位(8 字节)的双精度浮点数,起始地址可能需要是 8 的倍数。
- 性能提升:
- 访问对齐的数据,处理器通常只需一次内存访问操作即可完成。
- 如果数据未对齐(Misaligned),处理器可能需要进行两次内存访问操作,然后拼接出所需的数据片段。这不仅速度慢很多倍,在早期或某些嵌入式处理器上甚至会导致硬件异常(程序崩溃)。
- 原子性保证:
- 某些处理器架构保证对齐数据的读写操作是原子的(即在操作完成前不会被中断)。这对于实现无锁数据结构和确保数据一致性很重要。
- 缓存效率:
- 现代处理器使用高速缓存(Cache),数据传输以缓存行为单位(通常是 64 字节)。对齐的数据结构更容易完整地放入一个或多个缓存行中,减少跨缓存行访问的情况,从而提升缓存利用率和性能。
字节对齐是如何工作的?(以结构体为例)
编译器在分配内存给变量(尤其是结构体 struct 和联合体 union 的成员)时,会自动插入填充字节来确保每个成员都满足其自身的对齐要求。
例子:
struct MyStruct {
char a; // 1 字节
// 编译器插入 3 个填充字节 (Padding Bytes) 以满足 int 的对齐要求
int b; // 4 字节,要求按 4 字节对齐(地址是 4 的倍数)
char c; // 1 字节
// 编译器再插入 3 个填充字节,使整个结构体大小是最大成员大小(int: 4字节)的整数倍(为了数组连续存放)
}; // 总大小 = 1(char) + 3(padding) + 4(int) + 1(char) + 3(padding) = 12 字节
- 成员
a(1 byte): 可以放在任何地址(对齐要求是 1)。 - 成员
b(4 bytes): 要求地址是 4 的倍数。紧跟在a后的地址(假设结构体起始地址是 0,则a在 0,b期望在 4)不符合要求(地址 1 不是 4 的倍数)。因此编译器在a后面插入 3 个无意义的字节(地址 1, 2, 3),使b从地址 4 开始存放。 - 成员
c(1 byte): 可以放在地址 8。 - 结构体尾部填充: 为了确保当这个结构体被放入数组时,数组中的下一个结构体的第一个成员
a也能满足其可能的对齐要求(通常是按结构体中最严格的对齐要求来),编译器会在c后面再插入 3 个填充字节,使整个结构体的大小(12 字节)成为其最大成员对齐值(int b的对齐要求是 4)的整数倍(12 / 4 = 3)。
对齐值 (Alignment Requirement)
- 基本数据类型(
char,short,int,long,float,double, 指针等)的对齐要求通常等于它们自身的大小(在特定平台上)。char: 1 字节对齐short(2 bytes): 2 字节对齐int(4 bytes): 4 字节对齐double(8 bytes): 通常 8 字节对齐
- 结构体的对齐要求通常等于其成员中最严格(最大) 的对齐要求。数组的对齐要求与其元素的对齐要求相同。
控制对齐(编译器指令)
程序员有时需要手动控制对齐,例如:
- 节省空间: 通过重新排列结构体成员(按对齐要求从大到小或从小到大排序)可以减少填充字节。
- 与硬件或协议交互: 硬件寄存器映射、网络数据包或二进制文件格式通常有严格的对齐要求。
- 性能优化: 强制对齐到缓存行边界(如 64 字节)以避免
False Sharing。
C/C++ 中常用指令或属性:
#pragma pack(n)(GCC, Clang, MSVC): 设置最大对齐值为n字节(常用于紧密打包结构体)。__attribute__((aligned(n)))(GCC, Clang): 指定变量或类型的对齐值。__attribute__((packed))(GCC, Clang): 取消结构体/联合体内部的填充(成员紧挨着存放)。alignas(n)(C11/C++11): 标准方式指定对齐值。
总结
字节对齐是计算机系统底层为了高效访问内存数据而采用的核心机制。虽然有时会造成一些内存空间浪费(填充字节),但它带来的性能提升是显著的。编译器通常会自动处理对齐,但理解其原理对于进行底层编程、性能优化和理解内存布局至关重要。
嵌套的结构体 字节是如何对齐的
嵌套的结构体,字节又是如何对齐的呢 先来看下面的代码 typedef struct stu1 { char ary [ 5 ] ; int a; }stu1; typedef struct stu2
2023-11-20 16:01:17
什么是结构体的字节对齐现象
什么是结构体的字节对齐现象 程序员,咱都用代码说话,先上 code: (说明:以下代码均在 ARM 平台上,使用 Keil 进行编译测试) # define offset_of (TYPE
2023-11-20 15:55:04
stm32h743外部RAM非字节对齐访问,引起的hard fault
stm32h743外部RAM非字节对齐访问,引起的hard fault
资料下载
彭友旺
2021-12-09 09:21:15
单片机开发重点-字节对齐问题
单片机开发重点-字节对齐问题在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间。一般地,可以通过下面的方法来改变缺省的对界条件:使用伪指令 #pragma pack(n),C
资料下载
佚名
2021-11-13 13:06:02
Cortex-M3 栈的8字节对齐资料下载
电子发烧友网为你提供Cortex-M3 栈的8字节对齐资料下载的电子资料下载,更有其他相关的电路图、源代码、课件教程、中文资料、英文资料、参考设计、用户指南、解决方案等资料,希望可以帮助到广大的电子工程师们。
资料下载
孙成红
2021-04-11 08:42:12
对结构体的对齐理解上有点偏差
总结一下: 结构体对齐不再是简单的字节个数的拼凑,而是要与内存地址进行挂钩~一般我们也可以理解为内存地址分配是多少字节的倍数,就是多少直接
2022-08-10 18:08:28
解决单片机开发字节对齐问题的方法
单片机开发重点-字节对齐问题在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间。一般地,可以通过下面的方法来改变缺省的对界条件:使用伪指令 #pragma pack(n),C
align为什么要8字节对齐?
我知道数据储存的起始地址%对齐字节(N)=0才行,但是我不明白有两点问题1:UCOSIII的系统中的浮点数打印任务的堆栈大小要8字节
换一换
- 如何分清usb-c和type-c的区别
- 中国芯片现状怎样?芯片发展分析
- vga接口接线图及vga接口定义
- 芯片的工作原理是什么?
- 华为harmonyos是什么意思,看懂鸿蒙OS系统!
- 什么是蓝牙?它的主要作用是什么?
- ssd是什么意思
- 汽车电子包含哪些领域?
- TWS蓝牙耳机是什么意思?你真的了解吗
- 什么是单片机?有什么用?
- 升压电路图汇总解析
- plc的工作原理是什么?
- 再次免费公开一肖一吗
- 充电桩一般是如何收费的?有哪些收费标准?
- ADC是什么?高精度ADC是什么意思?
- dtmb信号覆盖城市查询
- EDA是什么?有什么作用?
- 苹果手机哪几个支持无线充电的?
- type-c四根线接法图解
- 华为芯片为什么受制于美国?
- 怎样挑选路由器?
- 元宇宙概念股龙头一览
- 锂电池和铅酸电池哪个好?
- 什么是场效应管?它的作用是什么?
- 如何进行编码器的正确接线?接线方法介绍
- 虚短与虚断的概念介绍及区别
- 晶振的作用是什么?
- 大疆无人机的价格贵吗?大约在什么价位?
- 苹果nfc功能怎么复制门禁卡
- amoled屏幕和oled区别
- 单片机和嵌入式的区别是什么
- 复位电路的原理及作用
- BLDC电机技术分析
- dsp是什么意思?有什么作用?
- 苹果无线充电器怎么使用?
- iphone13promax电池容量是多少毫安
- 芯片的组成材料有什么
- 特斯拉充电桩充电是如何收费的?收费标准是什么?
- 直流电机驱动电路及原理图
- 传感器常见类型有哪些?
- 自举电路图
- 通讯隔离作用
- 苹果笔记本macbookpro18款与19款区别
- 新斯的指纹芯片供哪些客户
- 伺服电机是如何进行工作的?它的原理是什么?
- 无人机价钱多少?为什么说无人机烧钱?
- 以太网VPN技术概述
- 手机nfc功能打开好还是关闭好
- 十大公认音质好的无线蓝牙耳机
- 元宇宙概念龙头股一览