Posted Sep 25, 2013 12:31 UTC (Wed) by busterb (subscriber, #560)
In reply to: Good one by ncm
Parent article: A perf ABI fix
I used to think bitfields were neat, until I found out how badly the performed on an embedded MIPS.
The difference between dereferencing a bitfield and just doing a (flags & FLAG) test was generally a 20-30% speedup on inner loops in an ISA like MIPS due to its insistence on aligned memory accesses. Similar thing with the 'packed' GCC attribute.
Posted Sep 26, 2013 8:51 UTC (Thu) by etienne (subscriber, #25256)
[Link]
> bitfield ... insistence on aligned memory accesses
There isn't any relation in between bitfields and alignment, so it would probably be better to fix the compiler than fix few random source files, long term...
Good one
Posted Sep 26, 2013 9:30 UTC (Thu) by khim (subscriber, #9252)
[Link]
Wouldn't that break the ABI? Long-term this may be a good idea, but short-term it'll be quite a problem.
Good one
Posted Sep 26, 2013 11:05 UTC (Thu) by etienne (subscriber, #25256)
[Link]
> Wouldn't that break the ABI?
No, instead of reading the 2nd bit of unaligned byte, the compiler emits code to read bit (2+8) of aligned word. Bit stay at the same place.
Good one
Posted Sep 26, 2013 12:56 UTC (Thu) by khim (subscriber, #9252)
[Link]
This will only work for read, not for writes. And even then only if int and not _Bool is used.
Good one
Posted Sep 26, 2013 16:17 UTC (Thu) by deater (subscriber, #11746)
[Link]
One thing not really addressed is how bitfields run opposite ways on little endian and big endian systems.
Not a problem in most cases, but perf_event describes some bitfields
such as struct perf_branch_entry that get written to disk directly.
So if you record a session, then move it to an opposite-endian machine and try to read it back in you have problems.
Good one
Posted Sep 27, 2013 12:05 UTC (Fri) by etienne (subscriber, #25256)
[Link]
> opposite ways on little endian and big endian systems
On my side of the world, you do have little-endian system and BI-endian systems: the processor may be big-endian, but then it always has to interact with at least one little-endian subsystem (could be as simple as a PCI card, more usually most subsystems).
Then, they added stuff at the virtual memory layer to describe that memory mapped area as either little or big endian, which solves a small part of the problem, two bit fields still increment as 0b00, 0b10, 0b01, 0b11.
Then, big endian processor sort of disappeared.
I still prefer:
struct status {
#ifdef LITTLE_ENDIAN
unsigned b1:1, b2:1, b3:1, unused:29;
unsigned xx;
#else
unsigned xx;
unsigned unused:29, b3:1, b2:1, b1:1;
#endif
}
than the 40 equivalent lines of #define, if I have a lot of those status.