Padding: Necessary or a waste of space?

Started by
4 comments, last by OberonZ 24 years, 6 months ago
I may be wrong, but on many architectures fetching data aligned on 4 byte boundaries is faster than fetching data on odd boundaries.

I dunno if this is the case with Intel but I suspect it is.

With many RISC architectures fetching unaligned data (trying to read a 4 byte value on an odd address for example) causes a processor exception. If you are on such an architecture then padding is generally necessary unless you want a big performance hit.

But again it depends what you are doing with this packed bit structure. On the other hand, having 13 bits packed together with no padding might complicate the code for your loops needlessly...

So the answer: it depends - what architecture, what's the data structure, what's the algorithm, etc.

------------------
-vince


-vince


Advertisement
Well, in my case the struct looks like this
code:
typedef struct tagTile{	// Index in a list of tile graphics	WORD	wTile;	// If the tile has an obstacle, or is otherwise non-walkable, the flag is set to 1	int		fBlocked:1;	// Fog Of War	// Only places that have been explored can be seen, otherwise they are coverd with	// black.	int		fFogOfWar:1;	int		nPadding:14;} Tile, * PTile;

where WORD is defined as unsigned short.

wTile is an index to a tile graphic, and the other two bits are styles for the tile. I guess I could resort to booleans for the two bitflags, but you can never be sure how they'll behave from one compiler to the next. I guess I could have the index as an DWORD and use two WORDs for fBlocked and fFog, but then the structure would be double in size

Basically, I'm trying to conserve as much memory as possible. I found that alot of people in my school (and some professionals!!) get lulled by the "Well, RAM is cheap" or "CPUs are getting faster" speech to justify wanton and gratuitous waste of resources.

Anyway, thanks for the info.
I guess I'll align it to 4 bytes to be on the safe side.

-OberonZ

[This message has been edited by OberonZ (edited October 14, 1999).]

---
PAGE FAULT: Please insert "Swap File, Disk 2"
and press any key to continue.
Rule #1 of aligning data is to declare large struct/class members before smaller ones, so the individual members are aligned. Assuming your ints are 32 bits, they are all misaligned because of your 1st WORD declaration. Some compilers may try to fix this, but I wouldn't rely on them for this stuff.

It sounds like you're talking about making the entire struct an alignable size, which helps if you create an array of these structs, but if not then padding out the struct won't do much except waste space. And you can't actually have any struct be 13bits. It will, at an absolute minimum, be rounded up to byte alignment, 16bits.

Nowadays, with the 'ram is cheap' theory, you have to really look at why you would use 8 or 16 bit values over 32bit ones. Granted they should use less space (although I believe the compiler CAN still pad it out), it is slower for the CPU to handle 8/16 bit math than 32bit math. Modern CPUs are simply structured to work in 32bits, and other types of usage take a performance hit. I am certainly not a believer in the 'cheap ram' theory (good god WORD, how much ram to you waste!), but in games speed comes first, and 32bit values are fast. I try to keep all often used vars of 32bit size (and definately aligned!), such as coords, and usually try to keep flags and such that are used a few times per frame of type BYTE when possible. It seems to be a good tradeoff.

Rock

All things must be divisible into even bytes which is why an array of 2 bit structures will take the same space as an array of 1 byte structures, the machine can only address bytes. Rock2000 did hit on something though, without optimization a declaration like:
struct x
{
int xflags:3;
int count;
int yflags:2;
};
would take AT LEAST 6 bytes (even though it could be rewritten to fit in 5), and on some platforms it would actually have to be padded to TWELVE bytes, because often ints must be aligned on addresses divisible by
four.

Even if the struct was rewritten, it would still take 6 or 8 bytes due to the alignment rules for ints. The general rule is, worst case, data must be aligned on a boundry that is divisible by its size (so on 64 bit platforms pointers must be aligned on 8 byte boundries).

If your curious...just use sizeof(tagTile) without manually adding the nPadding field and you'll see what pading the compiler will force on you anyway.

Another note...this pading occurs no matter wheither you declare arrays of the struct, or just one, because the compiler must compute the sizeof() value...and the value can't change arbitrarily from one module to the next...so be careful to turn the compiler's pading on or off for ALL of your modules, or you won't be able to link them.

[This message has been edited by Xai (edited October 17, 1999).]

Hi all,
Just a quick question. Given a structure that is whose size is some odd non power of two size (say, 19 bits). Is there a real benefit to adding another 13bit members so that it's padded to 32?

I remember reading/hearing something about that, but I don't rememeber.

Thanks,
-OberonZ

---
PAGE FAULT: Please insert "Swap File, Disk 2"
and press any key to continue.
You are on the wrong side of optimisation, when you use [int x : 1] the compiler generates just an BYTE and has to generate lengthy code to access the one bit in this BYTE.
I suggest that you try to avoid these construts and use the base C/C++ types you have to use (for this example an bool).
Alingment is a very crucial thing in compilers, on 32Bit systems (all Pentiums, newer Apple machines), the compiler tries to align the structs and classes to a DWORD(4 Byte) to get better results when copying and accessing data. But this is done internally. The best you can do is make the structs multiples of DWORDs long, to get the best results.
By the way an int is in Win32 4 Bytes long. The right size for a register.

Aidan

This topic is closed to new replies.

Advertisement