C++11 内存对齐

本文深入探讨了内存对齐的重要性,包括提升CPU读取数据的速度和减少数据访问错误。介绍了alignof与std::alignment_of的区别,alignas关键字如何改变变量对齐方式,std::aligned_storage的应用场景,以及std::max_align_t和std::align的功能与使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内存对齐alignas、alignof关键字

目录

内存对齐alignas、alignof关键字

为什么要做内存对齐

alignof和 std::alignment_of

Abstract

Demo

alignas

Abstract

Demo

std::aligned_storage

Abstract

max_align_t 和 std::align

Abstract

Demo


为什么要做内存对齐

Although memory is measured in bytes, most processors do not access memory in blocks of bytes. It accesses memory in units of double, four, eight,16, or even 32 bytes, which we refer to as memory access granularity.

Now consider a 4-byte access granularity processor taking variables of type INT (32-bit system), which can only start reading data from memory with address multiples of 4.

Without memory alignment, data can be stored anywhere. Now an int variable is stored in a sequence of four bytes starting at address 1. When the processor fetches the data, The first 4-byte block is read from address 0, eliminating unwanted bytes (address 0), then the next 4-byte block is read from address 4, also eliminating unwanted data (address 5,6,7), and finally the remaining two pieces of data are merged into the register. It takes a lot of work.

Simply put, memory alignment can improve the speed at which the CPU reads data and reduce errors in accessing data (some cpus must have memory alignment, otherwise pointer access errors).

尽管内存是以字节为单位,但是大部分处理器并不是按字节块来存取内存的.它一般会以双字节,四字节,8字节,16字节甚至32字节为单位来存取内存,我们将上述这些存取单位称为内存存取粒度.

现在考虑4字节存取粒度的处理器取int类型变量(32位系统),该处理器只能从地址为4的倍数的内存开始读取数据。

假如没有内存对齐机制,数据可以任意存放,现在一个int变量存放在从地址1开始的连续四个字节地址中,该处理器去取数据时,要先从0地址开始读取第一个4字节块,剔除不想要的字节(0地址),然后从地址4开始读取下一个4字节块,同样剔除不要的数据(5,6,7地址),最后留下的两块数据合并放入寄存器.这需要做很多工作.

简单的说内存对齐能够提高 cpu 读取数据的速度,减少 cpu 访问数据的出错性(有些 cpu 必须内存对齐,否则指针访问会出错)。

alignof和 std::alignment_of

Abstract

alignof用来获取内存对齐大小,alignof只能返回一个size_t而std::alignment_of继承自std::integral_constant,拥有value_type,type,value成员

Demo

  A a;
  cout << alignof(a) << endl;

  cout << std::alignment_of<A>::value << endl;   >>>> 1
  cout << std::alignment_of<B>::value << endl;   >>>> 2

alignas

Abstract

alignas可在定义变量时,改变当前变量的对齐值

Demo

_declspec(align(16)) class TEST {
    double a;
    double b;
    alignas(32) char c;
};
int main() {
    std::cout << alignof(TEST);//output: 32
    system("pause");
}

std::aligned_storage

Abstract

std::aligned_storage可以看成一个内存对齐的缓冲区

  template<std::size_t Len, std::size_t Align = /*default-alignment*/>
 
  struct aligned_storage;

max_align_t 和 std::align

Abstract

std::max_align_t用来返回当前平台的最大默认内存对齐类型,对于malloc返回的内存,其对齐和max_align_t类型的对齐大小应当是一致的

std::align用来在一大块内存中获取一个符合指定内存要求的地址

Demo

std::cout << alignof(std::max_align_t) << std::endl;

char buffer[] = "......";
void *ptr = buffer;
std::size_t space = sizeof(buffer) - 1;
std::align(alignof(int),sizeof(char),pt,space);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ym影子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值