在C ++中优化类实例的内存布局

时间:2012-04-03 07:48:06

标签: c++ memory memory-alignment

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

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

有没有办法找出非POD对象(如类实例)的内存布局? 我怎么能实现类包装类对象的东西呢?

谢谢, 丹

4 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:1)

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

您还可以阅读关于精彩Agner Fog C++ optimize guide的第7.18段:

  

类或结构的数据成员按照它们的顺序连续存储   每当创建类或结构的实例时都会声明。没有   将数据组织到类或结构中的性能损失。访问数据   类或结构对象的成员不会花费更多时间来访问简单变量。   大多数编译器会将数据成员与循环地址对齐以优化访问

答案 2 :(得分:0)

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

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

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

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

答案 3 :(得分:0)

关于非POD对象,我认为你应该阅读更多关于vTable,虚函数,虚拟继承的知识,以了解哪些事物的行或类对象的大小。事实上,类对齐哪些填充,类成员对齐只是一个因素导致类的大小。

这里有一些相关的网站,我认为它对你有所帮助。

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

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

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

    cl -d1reportAllClassLayout main.cpp