【问题标题】:Optimizing memory layout of class instances in C++在 C++ 中优化类实例的内存布局
【发布时间】:2012-04-16 20:45:44
【问题描述】:

将应用程序从 32 位升级到 64 位会增加指针大小和对象的内存占用。

我正在寻找尽可能减少对象内存占用的方法。 对于 POD 结构,我转储结构的内存布局,以找出如何打包成员并减少编译器填充。

有没有办法弄清楚非 POD 对象(例如类实例)的内存布局? 我怎样才能实现类似于打包类对象的东西?

谢谢, 丹

【问题讨论】:

  • 通常会有编译器特定的标志和编译指示,并且重新排序字段可能会产生影响。然而,所有这些都可能影响性能和互操作性
  • 你使用的是哪个编译器?
  • @dbbd btw 为什么您担心 64 位架构中的进程内存大小? 64 位架构可以支持巨大的虚拟内存大小。不像 32 位拱形
  • @weima 虚拟内存很大并不意味着应用程序使用的实际内存也一定很大
  • 您也可以使用不同的打包选项构建您的程序,并比较两种情况下的内存消耗(打印 sizeofs 或运行一些实际测试)。这可以帮助您确定是否值得继续进一步调查。

标签: c++ memory memory-alignment


【解决方案1】:

您可以使用 GCC 的 -Wpadded 通知您添加填充的位置,然后根据该信息重新排序,在某些情况下会减小大小。

强制打包数据对于内存中的表示来说不是一个好主意。

【讨论】:

    【解决方案2】:

    我不知道特定的非 POD 对象数据(即 vtable),尽管我认为这是由指针大小决定的。 无论如何,您可以使用GCCVisual Studio 都支持的编译器指令#pragma pack 来控制成员的对齐方式。

    你也可以在精彩Agner Fog C++ optimize guide上阅读第7.18段:

    类或结构的数据成员按它们的顺序连续存储 每当创建类或结构的实例时都会声明。没有 将数据组织成类或结构的性能损失。访问数据 类或结构对象的成员只需要访问一个简单变量的时间。 大多数编译器会将数据成员与舍入地址对齐以优化访问

    【讨论】:

      【解决方案3】:

      经验法则:从大到小;当元素大小是 2 的幂时,这可以提供完美的对齐,否则,可以进行手动优化。

      请注意,正确的对齐通常对速度至关重要,即使 CPU 从违规中恢复。虽然 x86 和 (AFAIK) x64 CPU 的手动未对齐访问在内部使用第二次读取,但未对齐读取“浪费”的时间通常远大于由于较小的工作集而节省的时间。因此,仅当您在多个 CPU 上运行比较时,我才会“紧密打包”。

      对于非 POD,您必须检查 sizeof(element)
      (如果有大量对象,我可能会使用生成 C++ 的简单解析器来转储这些大小)

      或者,PVS-Studio 可以分析结构大小并提供重新排序建议。我还没有考虑太多,但是您可以使用 eval 来确定它是否适合您。

      【讨论】:

      • 重新排序成员并不是一个简单的选择,因为有很多编码器/解码器和其他 RPC 东西,这总是令人头疼的问题。此外,对于 IO 绑定的应用程序,cpu 性能并不重要。我更喜欢打包和松散 CPU,而不是获得性能和松散内存——特别是对于这种类型的 IO 绑定应用程序。
      【解决方案4】:

      关于非 POD 对象,我认为您应该阅读更多有关 vTable、虚函数、虚继承的内容,以了解哪些事物会影响类或对象的大小。实际上,产生填充的类对齐,类成员对齐只是影响类大小的因素之一。

      这里有一些相关的网站,我想对你有帮助。

      1. 确定类对象的大小:http://www.cprogramming.com/tutorial/size_of_class_object.html

      2. 内存布局:http://www.phpcompiler.org/articles/virtualinheritance.html

      而且,如果您使用 MVSC,您可以使用 -d1reportAllClassLayout 转储解决方案中所有类的所有内存布局,如下所示:

      cl -d1reportAllClassLayout main.cpp
      

      【讨论】:

        猜你喜欢
        • 2015-05-25
        • 2016-09-11
        • 2010-11-18
        • 2013-08-07
        • 1970-01-01
        • 2014-01-29
        • 1970-01-01
        • 2010-12-29
        • 1970-01-01
        相关资源
        最近更新 更多