从硬件到语言,详解C++的内存对齐(memory alignment)
作者:)。
我们也可以写一个简单的程序测试一下自己的CPU对未对齐内存访问的支持,以下是代码:
#include <iostream> #include <chrono> using namespace std; using namespace std::chrono; milliseconds test_duration(volatile int * ptr) // 使用volatile指针防止编译器的优化 { auto start = steady_clock::now(); for (unsigned i = 0; i < 100'000'000; ++i) { ++(*ptr); } auto end = steady_clock::now(); return duration_cast<milliseconds>(end - start); } int main() { int raw[2] = {0, 0}; { int* ptr = raw; cout << "address of aligned pointer: " << (void*)ptr << endl; cout << "aligned access: " << test_duration(ptr).count() << "ms" << endl; *ptr = 0; } { int* ptr = (int*)(((char*)raw) + 1); cout << "address of unaligned pointer: " << (void*)ptr << endl; cout << "unaligned access: " << test_duration(ptr).count() << "ms" << endl; *ptr = 0; } cin.get(); return 0; }
我测试使用的电脑的CPU是Intel Core i7 2630QM,是intel 2代酷睿CPU,测试结果为:
address of aligned pointer: 000000668DEFFA78 aligned access: 282ms address of unaligned pointer: 000000668DEFFA79 unaligned access: 285ms
可以看出对齐与未对齐的内存访问没有性能上的差别。
在C++中修改对齐要求
一般情况下,我们不需要自定义对齐要求,但也会有很特殊的情况下需要做调整。C++中,我们可以使用alignas关键字修改一个类型、或者一个变量的对齐要求。例如:
class MyObject { char c; alignas(8) int i; short s; };
这样的话,变量i的对齐要求由原本的4变成了8,结果就是,i的字节数偏移由4变成了8,s的字节数偏移由8变成了12,MyObject的对齐要求也变成了8,大小变成了16。
我们也可以对MyObject的定义使用alignas:
class alignas(16) MyObject { char c; int i; short s; };
还可以在alignas里面写某个类型。也可以使用多个alignas,结果就是使用最大的对齐要求。例如以下MyObject的对齐要求就是16:
class alignas(int) alignas(16) MyObject { char c; int i; short s; };
alignas有一个限制,那就是不能用alignas改小对齐要求。例如以下的代码会报错:
alignas(1) int i;
另外,C++中,有一个特殊的类型:max_align_t,所有不大于他的对齐量叫做基础对齐量(fundamental alignment),比这个对齐量大的叫做扩展对齐量(extended alignment )。C++标准规定,所有平台必须要支持基础对齐量,而对于扩展对齐量的支持要看各个平台。一般来说max_align_t的对齐量等于long double的对齐量。
C++关于内存对齐的支持还有很多功能,例如查询对齐量的alignof关键字,可以创建任意大小任意对齐要求的类型的aligned_storage模板,还有方便模板编程的alignment_of等等,在此就不细述了。
相关文章:
-
-
Java开源生鲜电商平台-库存管理设计与架构(源码可下载) 说明:Java开源生鲜电商平台-库存管理设计与架构有以下几个功能 WMS的功能:1、业务... [阅读全文]
-
修改文件有e/enews/index.php /e/member/register/register.php加入了 ... [阅读全文]
-
sprign中的logging实现简介 对于spring架构,Jakarta Commons Logging API (JCL)是强制依赖的。spr... [阅读全文]
-
单例设计模式 目的:让类创建对象,在系统中只有唯一的实例,让每一次创建的对象返回的内存地址都是相同的。 __new__方法 使用类名创建对象时,py... [阅读全文]
-
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论