将应用程序从32位升级到64位会增加指针大小和对象的内存占用量。
我正在寻找尽可能减少对象内存占用的方法。 对于POD结构,我转储结构的内存布局,以找出如何打包成员并减少编译器填充。
有没有办法找出非POD对象(如类实例)的内存布局? 我怎么能实现类包装类对象的东西呢?
谢谢, 丹
答案 0 :(得分:4)
您可以使用GCC的-Wpadded
通知您添加填充的位置,然后根据该信息重新排序,在某些情况下缩小尺寸。
强制打包数据对于内存中的表示不是一个好主意。
答案 1 :(得分:1)
我不知道具体的非POD对象数据(即vtable),即使我认为这是由指针大小决定的。
无论如何,您可以使用GCC和Visual 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,虚函数,虚拟继承的知识,以了解哪些事物的行或类对象的大小。事实上,类对齐哪些填充,类成员对齐只是一个因素导致类的大小。
这里有一些相关的网站,我认为它对你有所帮助。
确定类对象的大小:http://www.cprogramming.com/tutorial/size_of_class_object.html
内存布局:http://www.phpcompiler.org/articles/virtualinheritance.html
并且,如果您使用MVSC,您可以使用-d1reportAllClassLayout转储解决方案中所有类的所有内存布局:
cl -d1reportAllClassLayout main.cpp