【发布时间】:2011-04-18 23:04:54
【问题描述】:
类对象的二进制体系结构中的成员顺序可能会以某种方式影响使用该类的应用程序的性能吗?我想知道如果答案是肯定的,如何确定 POD 成员的顺序,因为程序员通过声明的顺序定义了成员的顺序
【问题讨论】:
标签: c++ performance class object binary
类对象的二进制体系结构中的成员顺序可能会以某种方式影响使用该类的应用程序的性能吗?我想知道如果答案是肯定的,如何确定 POD 成员的顺序,因为程序员通过声明的顺序定义了成员的顺序
【问题讨论】:
标签: c++ performance class object binary
当然。 C++ 保证内存中对象的顺序与声明的顺序相同,除非有访问限定符介入。
直接相邻的对象更有可能位于同一缓存行上,因此一次内存访问将同时获取它们(或从缓存中刷新两者)。缓存的有效性也可以提高,因为其中有用数据的比例可能更高。简而言之,代码中的空间局部性转化为性能的空间局部性。
此外,正如 Jerry 在 cmets 中指出的那样,顺序可能会影响填充量。通过减小大小对成员进行排序,这也是通过减小对齐方式(通常将数组视为其类型的一个元素,并将成员结构视为其最对齐的成员)。不必要的填充可能会增加结构的总大小,从而导致更高的内存流量。
C++03 §9/12:
a 的非静态数据成员 (非联合)类声明没有 分配了中间的访问说明符,以便后面的成员拥有 类中的更高地址 目的。分配顺序 非静态数据成员由 访问说明符未指定 (11.1)。实施对齐 要求可能会导致两个 相邻成员不被分配 紧随其后;所以可能 管理空间要求 虚函数(10.3)和虚函数 基类 (10.1)。
【讨论】:
完全同意Potatoswatter。不过,关于 CPU 缓存行,应该再补充一点。
如果您的应用程序是多线程的并且不同的线程读/写结构的成员 - 确保这些成员不在同一缓存行中非常重要。
关键是,每当一个线程修改缓存在其他 CPU 中的内存地址时 - 该 CPU 立即使包含该地址的缓存行无效。这样不正确的成员顺序可能会导致不合理的缓存失效和性能下降。
【讨论】:
除了cache-line相关答案中描述的运行时性能,我认为还应该考虑内存性能,即类对象的大小。
由于padding,类对象的大小取决于成员变量声明的顺序。
以下声明可能需要 12 个字节
class foo {
char c1;
int i;
char c2;
}
但是,在简单地重新排序成员声明的顺序后,以下可能会占用 8 个字节
class bar {
int i;
char c1;
char c2;
}
在与 4 字节字对齐的机器中:
sizeof( foo ) = 12
但是
sizeof( bar ) = 8
【讨论】: