views:

143

answers:

3

May order of members in binary architecture of objects of a class somehow have an impact on performance of applications which use that class? and I'm wondering about how to decide order of members of PODs in case the answer is yes since programmer defines order of members via order of their declaraions

+17  A: 

Absolutely. C++ guarantees that the order of objects in memory is the same as the order of declaration, unless an access qualifier intervenes.

Objects which are directly adjacent are more likely to be on the same cacheline, so one memory access will fetch them both (or flush both from the cache). Cache effectiveness may also be improved as the proportion of useful data inside it may be higher. Simply put, spatial locality in your code translates to spatial locality for performance.

Also, as Jerry notes in the comments, order may affect the amount of padding. Sort the members by decreasing size, which is also by decreasing alignment (usually treat an array as just one element of its type, and a member struct as its most-aligned member). Unnecessary padding may increase the total size of the structure, leading to higher memory traffic.

C++03 §9/12:

Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).

Potatoswatter
Wow, I didn't realize it but I posted this answer 112 *seconds* after the question was posted!
Potatoswatter
@Potatoswatter_cool achievement!!!
Pooria
Also its size could matter. Since the x86 (and probably many other) processor has special opcodes for memory access with index register, an array of objects that have sizes of 1, 2, 4 or 8 bytes will be accessed faster.
ruslik
So when dealing with POD types since the order is defined by the programmer how could someone decide what order is best for performance?
Pooria
@Pooria: typically, if you have one member that's used a lot more than others, put it first (indirection is often faster than indirection with offset). If you have members that will (nearly) always be used together, keep them together physically. Other than that, you usually just sort by decreasing size to minimize padding.
Jerry Coffin
+1  A: 

Absolutely agree with Potatoswatter. However one more point should be added about the CPU cache lines.

If your application is multithreaded and different threads read/write members of your structure - it's very important to make sure those members are not within the same cache line.

The point is that whenever a thread modifies a memory address that is cached in other CPU - that CPU immediately invalidates the cache line containing that address. So that improper members order may lead to the unjustified cache invalidation and performance degradation.

valdo
+1  A: 

In addition to the runtime performance, described in the cache-line related answers, I think one should also consider memory performance, i.e. the size of the class object.

Due to the padding, the size of the class object is dependent on the order of member variable declaration.

The following declaration would probably take 12 bytes

class foo {
    char c1;
    int  i;
    char c2;
}

However, upon simple re-ordering of the order of member declaration, the following would probably take 8 bytes

class bar {
    int  i;
    char c1;
    char c2;
}

In machines aligned with 4-byte words:

sizeof( foo ) = 12

but

sizeof( bar ) = 8
ArunSaha