sluijten wrote:sje wrote:Also, bitfield access can be slower than explicit masking and shifting.
Really? Should be easy to measure a difference with perft.
Could bitfield performance also be faster than masking & shifting?
Or is masking & shifting going to be the 'upper speed limit' ?
Compiler writers don't usually put a lot of effort into the treatment of bitfields. Lots of compilers generate crappy code for them. So you will probably get faster code if you write the masking and shifting yourself.
You should also do the masking and shifting yourself if the placement of the bitfields matters, if you want them in a certain order within the word so you can sort by the whole word. If you don't care about those things then using bitfields can help you have nice readable code.
If you go with bitfields, there are some things to be careful about:
* Try to use a type large enough to contain all of your bitfields so that it doesn't have to insert padding bits between bitfields. If the type you use is too small it will waste padding bits rather than trying to split the field in two parts.
* Use an unsigned type. If you just use something like "int" you may get some nasty surprises.
* Single-bit fields work nicely as flags or bool replacements. You can write inline setter and getter methods that cast to and from the "proper" type for what you want to store (bool, an enum, etc.). Putting your bitfields into a struct inside a union with a regular integer-typed field can also be handy (you can use that member for things like copy constructors). It might make them more annoying to initialize though.
* Don't assume your compiler is smart enough to merge a bunch of assignments of literal values to the bitfields into a single assignment to the underlying type. If you have any code like that where you care about the performance (e.g. if you assign them all in the constructor, and you're constructing an array of 1000 of them) then you should check the generated code to make sure its not too stupid.