Peeter Joot's (OLD) Blog.

Math, physics, perl, and programming obscurity.

more on C structure padding (space impact).

Posted by peeterjoot on November 12, 2009

On reading my previous post Daniel said,

“This should be part of the lab’s orientation, I think. It’s just too darned important for developers to NOT know.”

Daniel worked on parts of our code where making binary incompatible changes was not allowed since they were written to disk and doing this had migration impact. In such a case this statement is quite true. For a general developer, lets enumerate some of the reasons that one would care.

The biggest reason is awareness of the space that your structure uses. Here’s an example of a data structure that we used to have in our code, for which thousands and thousands of instances would be allocated in the course of executing a single SQL statement.

struct X
{
   short    a ;
   short    b ;
   void *   p ;
   short    a ;
   short    b ;
} ;

In our 32-bit days this was a reasonable layout. There are no gaps between any of the members, and the total structure size is 12 bytes.

When we ported to 64-bit the pointer size increases by 4 bytes, so this will neccessarily impact the amount of memory that we use. Consider what the compiler does with this structure though:

struct X
{
   short    a ;
   short    b ;
                     // <<< 4 byte pad here so that p alignment on 8 byte multiple
   void *   p ;
   short    a ;
   short    b ;
                     // <<< 4 byte pad tail pad here so that size is 8 byte multiple
} ;

Switching to 64-bit compilation doesn’t just increase the structure size by 4 bytes, but increases the structure size by 12 bytes, doubling the required space despite the fact that this structure only had one pointer in it!

After fixing up the hacky code that depended on the layout of this structure, we ended up rearranging this. If I recall correctly (it has since changed again), the new layout was

struct X
{
   void *   p ;
   short    a ;
   short    b ;
   short    a ;
   short    b ;
} ;

Here there is no padding between elements and the structure size increase due to the 64-bit port was only 4 bytes, something much easier to sweep under the rug, especially since we were switching to machines where 4Gb of memory was now just the starting point;)

Generally, if you want to avoid excessive compiler padding of your structures you can follow the rule of thumb: order members from biggest to smallest. When performance matters you may have to compromise since there can be positive performance gain by putting the most accessed things right at the beginning, but this rule of thumb for not being a space pig is still a good one. If you only allocate one instance of the structure it doesn’t matter, but if you do thousands or millions of them, it can easily add up (and it did for us).

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: