Optimizing memory layout of class instances in C++
Asked Answered
S

4

7

Upgrading an application from 32 to 64 bit increases the pointer size and the memory footprint of objects.

I am looking for methods to reduce the memory footprint of objects as much as possible. For POD structs I dump the memory layout of the structure to figure out how to pack the members and reduce compiler padding.

Is there a way to figure out the memory layout of non-POD objects such as class instances? How could I achieve something similar to packing of class objects?

Thanks, Dan

Soloma answered 3/4, 2012 at 7:48 Comment(8)
in general there will be compiler specific flags and pragmas, and reordering fields may have an effect. However all of this may affect performance and interoperabilitySnail
Which compiler are you using?Tortuga
@Soloma btw why are you worried about process memory size in 64 bit architecture? a 64 bit architecture can support a huge virtual memory size. unlike 32 bit archNappy
@Nappy The fact that the virtual memory size is huge does not imply that the actual memory used by the application must be huge as wellTortuga
you may also build your program with different packing options and compare memory consumption in both cases (print sizeofs or run some real tests). This may help you to figure out whether it is worthy to continue further investigations or not.Embankment
Sorry, using gcc on linux/centos 64bit arch.Soloma
@Nappy Although this is linux, the application environment is more like embedded. Virtual memory cannot go beyond physical. Also, the app implements its own allocation scheme - it allocates a large amount of memory on start and overrides "new" to use this allocated memory.Soloma
From the technical perspective, there is no difference between POD and non-POD class/struct. Both are structs underneath.Peshawar
H
6

You can use GCC's -Wpadded to inform you where padding is added, then reorder based on that information, reducing the size in some cases.

Force-Packing the data is not a good idea for representations in memory.

Halbeib answered 3/4, 2012 at 8:3 Comment(0)
T
1

I do not know about specific non-POD objects data (i.e. vtable), even though I suppose that is dictated by the pointer size. Anyway, you can control the alignment of members with the compiler directive #pragma pack that is supported both by GCC and Visual Studio.

You can also read paragraph 7.18 on wonderful Agner Fog C++ optimize guide:

The data members of a class or structure are stored consecutively in the order in which they are declared whenever an instance of the class or structure is created. There is no performance penalty for organizing data into classes or structures. Accessing a data member of a class or structure object takes no more time than accessing a simple variable. Most compilers will align data members to round addresses in order to optimize access

Tortuga answered 3/4, 2012 at 7:56 Comment(0)
M
0

Rule of thumb: largest to smallest; this gives perfect alignment when the element sizes are powers of two, otherwise, manual optimizations are possible.

Note that proper alignment is usually essential for speed, even if the CPU recovers from violations. While x86 and (AFAIK) x64 CPU's hand misaligned access internally with a second read, the time "wasted" on a misalignment read is usually much larger than the time saved due to a smaller working set. So I would "tightly pack" only when you run comparisons on multiple CPU's.

For non-POD's you'd have to check the sizeof(element)'s.
(If there are tons of objects, I'd probably go with a simple parser generating the C++ to dump these sizes)

Alternatively, PVS-Studio has an analysis of struct sizes and gives reordering suggestions. I haven't considered them much yet, but you could use the eval to find out if it's working for you.

Mackmackay answered 3/4, 2012 at 9:11 Comment(1)
Reordering members is not an easy option since there's a lot of encoders/decoders and other RPC stuff which is always a big headache. Also, for an IO bound application, cpu performance is not important. I'd prefer to pack and loose CPU than gain performance and loose memory - specifically for this type of IO bound applications.Soloma
R
0

Relating to non-POD objects, I think you should read more about vTable, virtual function, virtual inheritance to know which things conduct the size of class or object. In fact, class alignment which yeilds padding, class member alignment only one of factors conduct class's size.

Here there are some related website, I think it can be helpful to you.

  1. Determine the size of class object: http://www.cprogramming.com/tutorial/size_of_class_object.html

  2. Memory layout: http://www.phpcompiler.org/articles/virtualinheritance.html

And, if you use MVSC, you can dump all memory layout of all class in your solution with -d1reportAllClassLayout like that:

cl -d1reportAllClassLayout main.cpp
Raki answered 3/6, 2015 at 7:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.