类对象成员的顺序对性能有影响吗?

发布于 2024-09-25 14:26:47 字数 95 浏览 5 评论 0原文

类对象的二进制体系结构中的成员顺序可能会以某种方式影响使用该类的应用程序的性能吗?我想知道如果答案是肯定的,如何决定 POD 成员的顺序,因为程序员通过声明的顺序定义成员的顺序

May order of members in binary architecture of objects of a class somehow have an impact on performance of applications which use that class? and I'm wondering about how to decide order of members of PODs in case the answer is yes since programmer defines order of members via order of their declaraions

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我不是你的备胎 2024-10-02 14:26:47

绝对地。 C++ 保证内存中对象的顺序与声明的顺序相同,除非访问限定符介入。

直接相邻的对象更有可能位于同一缓存行上,因此一次内存访问将同时获取它们(或从缓存中刷新它们)。高速缓存的有效性也可以得到提高,因为其中有用数据的比例可能更高。简而言之,代码中的空间局部性会转化为性能的空间局部性。

此外,正如杰瑞在评论中指出的那样,顺序可能会影响填充量。按大小递减对成员进行排序,这也是通过对齐递减(通常将数组视为其类型的一个元素,将成员结构视为其最对齐的成员)。不必要的填充可能会增加结构的总大小,从而导致更高的内存流量。

C++03 §9/12:

a 的非静态数据成员
声明的(非联合)类没有
分配中间的访问说明符,以便后面的成员有
类内较高地址
目的。的分配顺序
非静态数据成员由
访问说明符未指定
(11.1)。实施调整
要求可能会导致两个
相邻成员不予分配
紧接着彼此;所以可能
管理空间要求
虚函数(10.3)和虚函数
基类(10.1)。

Absolutely. C++ guarantees that the order of objects in memory is the same as the order of declaration, unless an access qualifier intervenes.

Objects which are directly adjacent are more likely to be on the same cacheline, so one memory access will fetch them both (or flush both from the cache). Cache effectiveness may also be improved as the proportion of useful data inside it may be higher. Simply put, spatial locality in your code translates to spatial locality for performance.

Also, as Jerry notes in the comments, order may affect the amount of padding. Sort the members by decreasing size, which is also by decreasing alignment (usually treat an array as just one element of its type, and a member struct as its most-aligned member). Unnecessary padding may increase the total size of the structure, leading to higher memory traffic.

C++03 §9/12:

Nonstatic data members of a
(non-union) class declared without an
intervening access-specifier are allocated so that later members have
higher addresses within a class
object. The order of allocation of
nonstatic data members separated by an
access-specifier is unspecified
(11.1). Implementation alignment
requirements might cause two
adjacent members not to be allocated
immediately after each other; so might
requirements for space for managing
virtual functions (10.3) and virtual
base classes (10.1).

嘿咻 2024-10-02 14:26:47

完全同意土豆拍的观点。不过,关于 CPU 高速缓存线还需要补充一点。

如果您的应用程序是多线程的,并且不同的线程读取/写入结构的成员 - 确保这些成员不在同一缓存行中非常重要。

要点是,每当线程修改缓存在其他 CPU 中的内存地址时,该 CPU 就会立即使包含该地址的缓存行无效。因此,不正确的成员顺序可能会导致不合理的缓存失效和性能下降。

Absolutely agree with Potatoswatter. However one more point should be added about the CPU cache lines.

If your application is multithreaded and different threads read/write members of your structure - it's very important to make sure those members are not within the same cache line.

The point is that whenever a thread modifies a memory address that is cached in other CPU - that CPU immediately invalidates the cache line containing that address. So that improper members order may lead to the unjustified cache invalidation and performance degradation.

花想c 2024-10-02 14:26:47

除了缓存行相关答案中描述的运行时性能之外,我认为还应该考虑内存性能,即类对象的大小。

由于填充,类对象的大小取决于成员变量的顺序宣言。

以下声明可能需要 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

In addition to the runtime performance, described in the cache-line related answers, I think one should also consider memory performance, i.e. the size of the class object.

Due to the padding, the size of the class object is dependent on the order of member variable declaration.

The following declaration would probably take 12 bytes

class foo {
    char c1;
    int  i;
    char c2;
}

However, upon simple re-ordering of the order of member declaration, the following would probably take 8 bytes

class bar {
    int  i;
    char c1;
    char c2;
}

In machines aligned with 4-byte words:

sizeof( foo ) = 12

but

sizeof( bar ) = 8
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文