【问题标题】:does order of members of objects of a class have any impact on performance?类对象成员的顺序对性能有影响吗?
【发布时间】:2011-04-18 23:04:54
【问题描述】:

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

【问题讨论】:

    标签: c++ performance class object binary


    【解决方案1】:

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

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

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

    C++03 §9/12:

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

    【讨论】:

    • 哇,我没有意识到,但我在问题发布后 112 发布了这个答案!
    • 它的大小也很重要。由于 x86(可能还有许多其他)处理器具有特殊的操作码,用于通过索引寄存器访问内存,因此访问大小为 1、2、4 或 8 字节的对象数组将更快。
    • 那么在处理 POD 类型时,由于顺序是由程序员定义的,那么人们如何决定哪种顺序最适合性能?
    • @Pooria:通常,如果您有一个成员比其他成员使用得更多,请将其放在第一位(间接通常比使用偏移的间接更快)。如果您有(几乎)总是一起使用的成员,请将它们物理上保持在一起。除此之外,您通常只需按减小大小进行排序以最小化填充。
    【解决方案2】:

    完全同意Potatoswatter。不过,关于 CPU 缓存行,应该再补充一点。

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

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

    【讨论】:

      【解决方案3】:

      除了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
      

      【讨论】:

        猜你喜欢
        • 2012-09-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-05
        • 1970-01-01
        • 1970-01-01
        • 2020-11-11
        • 2011-11-12
        • 2014-01-05
        相关资源
        最近更新 更多