C++ 内存对齐——我们应该关心吗?

标签 c++ memory-alignment

<分区>

考虑在具有以下类型对齐的 x64 位 Windows 操作系统上工作:

C++ build in types alignments on my pc

据我所知,做这样的事情是非常糟糕的:

struct X_chaotic
{
    bool flag1;
    double d1;
    bool flag2;
    double d2;
    bool flag3;
    double d3;
    //... and so on ...
};

根据 C++ Alignment, Cache Line and Best PracticeData structure alignment , 写这个应该更好/更快并且更紧凑:

struct X_alignOrder
{
    double d1;
    double d2;
    double d3;
    //... all other doubles ...
    bool flag1;
    bool flag2;
    bool flag3;
    //... all other bools ...
};

成员按照对齐大小的顺序声明,从最高对齐开始。

可以肯定地说按对齐大小对数据成员的声明排序是个好主意吗?你会说这是最佳实践吗?还是没有区别?

(我听说编译器不能重新排列定义的顺序,因为 C++ 标准,这甚至适用于在类的访问说明符 block 中声明的所有数据成员)

因为我从未在 Scott Meyers 的书中或 Bjarne Stroustrup 的书中读到过这方面的内容,所以我想知道我是否应该开始通过日常工作的对齐方式重新排序数据声明。

最佳答案

这比看起来要复杂得多。

通过根据对齐需要对成员进行排序,您将节省一些填充字节,并且总大小会更小。如果内存紧张,或者如果这意味着该类型可以放入单个缓存行而不是两个或三个,这可能对您很重要。

另一方面;如果您经常访问过去靠得很近的成员,那么以前它们通常会被 CPU 预取器一起拉入缓存,但现在在重组类后不会了。那么您可能会节省内存但会牺牲运行时性能。

这里的性能也可能因不同的 CPU 和不同的编译器/编译器选项而有很大差异。

您需要在实际环境中运行一些基准测试,以了解哪种性能最适合您。

另请记住,重新排列您的成员变量会改变初始化顺序,如果成员相互依赖,这可能很重要(foo 初始化 bar,因此 foo 需要先初始化,等等)。

关于C++ 内存对齐——我们应该关心吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57244787/

相关文章:

C++ 类内存对齐

linux - Linux内核中的IS_ALIGNED宏是做什么的?

raspberry-pi - Raspberry PI 版本 1 未检测到未对齐的访问

c++ - 从 C++ 文件中读取的奇怪数组

c++ - 注册数据 "chunks"的最佳设计模式是什么?

c++ - QNetworkConfigurationManager::allConfigurations() 没有列出 WLAN

c++ - 重载多个运算符时出现“不匹配”错误

c++ - 从循环添加到结构 (c++)

c - gcc 使用 malloc 进行内存对齐

c++ - 类/结构成员是否总是按照声明的顺序在内存中创建?