Page 1 of 1

Named bit fields efficiency and reordering

Posted: Tue May 28, 2013 1:40 pm
by gsingh2011
I'm always a bit hesitant to use named bitfields in C because I hear all of these rumors about efficiency and the reordering of fields. I've never heard a definitive answer on this, and it's hard to test because I hear that part of the problem is that it varies between compilers.

So does anyone know if using named bit fields is less efficient that using regular shifts and masks? And is the compiler allowed to reorder named bit fields in a struct? I know the compiler isn't allowed to reorder regular fields, but I'm not sure if that applies to named bit fields as well.

Re: Named bit fields efficiency and reordering

Posted: Tue May 28, 2013 2:01 pm
by bluemoon
The compiler should not alter the logical order of bit fields, however, at least the following is not strictly defined:
1. byte order. This not defined by the specification, although there is no good reason to not use host's native order.
2. storage unit. The compiler is free to choose any word size. For example if the compiler uses 8-bit as unit size, it may also break down an 10-bit variable across 2 units. It may also choose to use 16, 32, 64bit, etc as native unit.
3. top-down or bottom up. The compiler is freely to start bits from bit[0] or bit[N-1], where N is the unit size.
4. padding. If two bit-field variables cannot be stored within same unit, the compiler may inject padding across units.

In short, bit-fields is logical, it's open for implementation for the underlying storage pattern.

Re: Named bit fields efficiency and reordering

Posted: Wed May 29, 2013 12:36 am
by Brendan
Hi,
gsingh2011 wrote:So does anyone know if using named bit fields is less efficient that using regular shifts and masks?
I doubt that bit fields are less efficient than shifts and masks (and I'd suspect the compiler converts the former into that latter anyway).

I would expect that normal fields are almost always faster than both bitfields and shifts and masks; unless RAM bandwidth is your bottleneck (e.g. imagine an array of structures that doesn't fit in the cache if the fields are chars/shorts/ints but does fit in the cache if you use bitfields).
gsingh2011 wrote:And is the compiler allowed to reorder named bit fields in a struct? I know the compiler isn't allowed to reorder regular fields, but I'm not sure if that applies to named bit fields as well.
The compiler can't reorder bitfields; but the order is implementation defined and so is things like padding, etc.

However...

Imagine if you have a header file that declares some structures (with or without bitfields), a C file that creates some structures and another C file that contains code that uses the structures created in the first C file; and you compile both C files separately. In this case the something has to ensure that both object files agree on the format of the structures, otherwise after they're linked together the final executable will be broken. This is why a compiler can't reorder structure fields and bitfields - there's no way to ensure that separately compiled object files will agree on the format otherwise, and therefore no way to optimise structures to improve performance (e.g. most frequently accessed stuff together) or to reduce size (e.g. reorder to reduce padding). Because (in theory) you're meant to be able to link object files generated by different compilers together; this also means that everything that's "implementation defined" for bitfields must actually be "object file format defined" (or more correctly "ABI defined"), and it can't be "defined by each specific compiler's implementation".


Cheers,

Brendan

Re: Named bit fields efficiency and reordering

Posted: Wed May 29, 2013 1:16 am
by bluemoon
Brendan wrote:Because (in theory) you're meant to be able to link object files generated by different compilers together; this also means that everything that's "implementation defined" for bitfields must actually be "object file format defined" (or more correctly "ABI defined"), and it can't be "defined by each specific compiler's implementation".
In reality if the two compiler has different padding (by default or extra compiler flags), or if one of them starts bit from top-down and the other is bottom-top, the resulting binary will be broken. And can you really blame gcc, VC, clang, or whichever compiler and ask them to agree on implementation defined stuff?

To the extreme extend, an unwise programmer may feed different flags into same compiler for different source files, and it can be broken if linked together.

Re: Named bit fields efficiency and reordering

Posted: Thu May 30, 2013 4:45 am
by Brendan
Hi,
bluemoon wrote:
Brendan wrote:Because (in theory) you're meant to be able to link object files generated by different compilers together; this also means that everything that's "implementation defined" for bitfields must actually be "object file format defined" (or more correctly "ABI defined"), and it can't be "defined by each specific compiler's implementation".
In reality if the two compiler has different padding (by default or extra compiler flags), or if one of them starts bit from top-down and the other is bottom-top, the resulting binary will be broken. And can you really blame gcc, VC, clang, or whichever compiler and ask them to agree on implementation defined stuff?
What I'm saying is that the "implementation defined" details are defined in the relevant specification (e.g.
"System V Application Binary Interface AMD64 Architecture Processor Supplement"); and that all compilers that comply with the same ABI specification must comply with the same ABI specification (and therefore there shouldn't be problems linking object files from different compilers that use the same ABI).

For 64-bit 80x86 there are 2 of these ABI specifications - the System V ABI, and Microsoft's ABI. This means that as long as you don't mix them (e.g. try to link ELF and PE together) there won't be any problem; regardless of which languages (see note!), which compiler/s or which settings are used.

Note: as always, C++ is an exception to the rule - in general it's a mangled mess that breaks more than it fixes; and in this specific case "mangling" can be taken literally. ;)


Cheers,

Brendan