memory alignment of a struct

G

Guest

Hello everyone,


I heard when define a struct, it is important to make the size of the struct
memory aligned.

For example,

Code:
struct foo
{
char p;
char[3] align;
};

Code:
struct goo
{
char p;
};

struct foo is better than struct goo, even if we only use member p.

Allocate 3 bytes to align with memory. But I do not know why make memory
aligned is better. Any reasons? (for example, prevent memory from running
out?)


thanks in advance,
George
 
C

Carl Daniel [VC++ MVP]

George said:
Hello everyone,


I heard when define a struct, it is important to make the size of the
struct memory aligned.

As a general rule, you shouldn't worry about this - the compiler will take
care of it for you by adding hidden padding members where appropriate
(unless you've used #pragma pack or the /Zp command line option to set
structure packing to 1 bytes).
For example,

Code:
struct foo
{
char p;
char[3] align;
};

Code:
struct goo
{
char p;
};

struct foo is better than struct goo, even if we only use member p.

Actually, it's not. The natural alignment of 'char' is 1 byte, so padding
this structure accomplishes nothing.
Allocate 3 bytes to align with memory. But I do not know why make
memory aligned is better. Any reasons? (for example, prevent memory
from running out?)

It's better because it's faster - or at the least not slower. Generally,
accessing an object located on it's "natural alignment" is considerably
faster. For example, a 4-byte int (long, etc) should be located at an
address that's a multiple of 4.

On some architectures (Itanium, for example), the CPU will actually generate
a fault when an attempt is made to access an unaligned object and the access
will actually be performed by a fault handler, making it literaly 1000's of
times slower.

On x86 the penalty can be a 2x-4x increase in access time (decrease in
access performance) if objects are not properly aligned in memory.

-cd
 
G

Guest

Hi Carl,


A great reply! Let me do a summary to confirm -- the key point is, struct
alignment will improve performance, at lease not degrade. Right?

Carl Daniel said:
George said:
Hello everyone,


I heard when define a struct, it is important to make the size of the
struct memory aligned.

As a general rule, you shouldn't worry about this - the compiler will take
care of it for you by adding hidden padding members where appropriate
(unless you've used #pragma pack or the /Zp command line option to set
structure packing to 1 bytes).
For example,

Code:
struct foo
{
char p;
char[3] align;
};

Code:
struct goo
{
char p;
};

struct foo is better than struct goo, even if we only use member p.

Actually, it's not. The natural alignment of 'char' is 1 byte, so padding
this structure accomplishes nothing.
Allocate 3 bytes to align with memory. But I do not know why make
memory aligned is better. Any reasons? (for example, prevent memory
from running out?)

It's better because it's faster - or at the least not slower. Generally,
accessing an object located on it's "natural alignment" is considerably
faster. For example, a 4-byte int (long, etc) should be located at an
address that's a multiple of 4.

On some architectures (Itanium, for example), the CPU will actually generate
a fault when an attempt is made to access an unaligned object and the access
will actually be performed by a fault handler, making it literaly 1000's of
times slower.

On x86 the penalty can be a 2x-4x increase in access time (decrease in
access performance) if objects are not properly aligned in memory.

-cd


regards,
George
 
T

Tom Widmer [VC++ MVP]

George said:
Hi Carl,


A great reply! Let me do a summary to confirm -- the key point is, struct
alignment will improve performance, at lease not degrade. Right?

Right, but the compiler automatically inserts padding into your structs
to give the correct alignment for types. e.g.

struct foo
{
char c;
int i;
};

Typically, the compiler will actually generate an 8 byte struct like this:

struct foo
{
char c;
char[3]; //unnamed padding
int i;
};

You can control this using #pragma pack. As a general rule, never add
your own alignment members, since it just makes your code less portable
for no benefit. If you leave it to the compiler, then the compiler knows
what's the best way to align things for the target architecture.

Tom
 
B

Ben Voigt

George said:
Hi Carl,


A great reply! Let me do a summary to confirm -- the key point is, struct
alignment will improve performance, at lease not degrade. Right?

No, in some cases it can degrade performance. The cost on x86 for unaligned
access is balanced against the decreased amount of data that fits in the CPU
cache, so the most performant packing is application-dependent.
Carl Daniel said:
George said:
Hello everyone,


I heard when define a struct, it is important to make the size of the
struct memory aligned.

As a general rule, you shouldn't worry about this - the compiler will
take
care of it for you by adding hidden padding members where appropriate
(unless you've used #pragma pack or the /Zp command line option to set
structure packing to 1 bytes).
For example,

Code:
struct foo
{
char p;
char[3] align;
};

Code:
struct goo
{
char p;
};

struct foo is better than struct goo, even if we only use member p.

Actually, it's not. The natural alignment of 'char' is 1 byte, so
padding
this structure accomplishes nothing.
Allocate 3 bytes to align with memory. But I do not know why make
memory aligned is better. Any reasons? (for example, prevent memory
from running out?)

It's better because it's faster - or at the least not slower. Generally,
accessing an object located on it's "natural alignment" is considerably
faster. For example, a 4-byte int (long, etc) should be located at an
address that's a multiple of 4.

On some architectures (Itanium, for example), the CPU will actually
generate
a fault when an attempt is made to access an unaligned object and the
access
will actually be performed by a fault handler, making it literaly 1000's
of
times slower.

On x86 the penalty can be a 2x-4x increase in access time (decrease in
access performance) if objects are not properly aligned in memory.

-cd


regards,
George
 
N

Nathan Mates

A great reply! Let me do a summary to confirm -- the key point is, struct
alignment will improve performance, at lease not degrade. Right?

Generally, yes. However, if you make a pathological structure, the
padding can be so bad that memory usage really spikes. And that can
cause performance issues.

It's really NOT all that hard to avoid just about all padding
issues, and make things pretty close to optimal before the compiler
gets to it: just rearrange member variables to put like-types adjacent.
For example, instead of a struct that goes

struct foo
{
double d1;
char c1;
double d2
char c2;
};

Just do

struct foo
{
double d1;
double d2;
char c1;
char c2;
}

So, just manually shuffle the struct items so that all items of
each type of variable (double, pointer, float, int, short, char, etc)
are adjacent. I also listed those types roughly by size, largest to
smallest, which could also help padding issues.

I wish there was a compiler switch to allow the compiler to do this
kind of shuffling automatically. There's a few cases where some code
that really "knows" too much about offsets might blow up, but like
aliasing, this is a useful optimization for most cases.

Nathan Mates
 
G

Guest

NM- [Wed, 04 Apr 2007 17:50:40 -0000]:
I wish there was a compiler switch to allow the compiler to do this
kind of shuffling automatically. There's a few cases where some code
that really "knows" too much about offsets might blow up, but like

That would be a nightmare. The struct is in
a header, used by perhaps many files, maybe
other projects in a solution, etc. All it takes
is to forget adding that switch to one - perhaps
now, perhaps next year - and it all blows up,
hopefully real loud.

Better, if this were to happen, is to add a
#pragma before the struct define, or yet another
non-std keyword, __alignthismessbest struct s.

If this were library code, it would mean every
compiler that used it would have to understand
__alignthismessbest. Not that this is more of
a problem than the various pack()s can be.

Count me as, NOT in favor. Unless you've got
a huge array of these structs, it's not going
to make much of a molehill, anyway. And if it
were to, and you knew enough to use __alignthis
messbest, you'd already have in place a do-a-
best-align layout.
 
N

Nathan Mates

NM- [Wed, 04 Apr 2007 17:50:40 -0000]:
I wish there was a compiler switch to allow the compiler to do this
kind of shuffling automatically. There's a few cases where some code
that really "knows" too much about offsets might blow up, but like
That would be a nightmare. The struct is in a header, used by
perhaps many files, maybe other projects in a solution, etc. All it
takes is to forget adding that switch to one - perhaps now, perhaps
next year - and it all blows up, hopefully real loud.

Are you saying that because people could possibly cause things to
go wrong that an option should be removed? To which I say: if you
can't stand the heat, get out of the kitchen. Or go use another
language. There's already a dozen compiler *OPTIONS* that'll do what
you claim right now -- __cdecl vs __fastcall will blow up things right
now. Should that get yanked? Passing structs with different #pragma
pack can break other things. Why give the option to assume no aliasing
if that'll cause proven code malfunctions in certain cases. C/C++ is
all about giving yourself bigger guns to shoot with. The fact that you
*can* shoot yourself in the foot is a sometimes-useful feature.

Clue time: I didn't say that struct-shuffling should be on 100% of
the time. I want a knob to tweak the compiler. If you don't think it'd
be useful, then you don't have to use it. Especially in games, when
we're fighting for bytes of memory, it'd be a darn useful OPTION.

Nathan Mates
 
B

Ben Voigt

NM- [Wed, 04 Apr 2007 17:50:40 -0000]:
I wish there was a compiler switch to allow the compiler to do this
kind of shuffling automatically. There's a few cases where some code
that really "knows" too much about offsets might blow up, but like

That would be a nightmare. The struct is in
a header, used by perhaps many files, maybe
other projects in a solution, etc. All it takes
is to forget adding that switch to one - perhaps
now, perhaps next year - and it all blows up,
hopefully real loud.

Better, if this were to happen, is to add a
#pragma before the struct define, or yet another
non-std keyword, __alignthismessbest struct s.

If this were library code, it would mean every
compiler that used it would have to understand
__alignthismessbest. Not that this is more of
a problem than the various pack()s can be.

I agree that it needs to be specified on a per-type basis, using __declspec
or a new keyword. That way, you can optimize all the data structures which
are internal to your code, while keeping the existing rules for types that
are part of your public interface.

Or perhaps, a compiler switch that enables optimization, with a pragma that
inhibits it for all types in the file and included files. That way you cna
throw it into your public header files and all your private structures get
optimized.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top