Re: bitfields

From: Herbert Kremser (kremser@flinux.tu-graz.ac.at)
Date: 11/26/95


On Sun, 26 Nov 1995, Pink Floyd wrote:

> Does anyone know if bitfields are much less efficient than bitvectors?
> For various reasons, I was considering the idea of switching all the
> bitvectors over to bitfields, something like this:
> currently, chars have an int affected_by, where each affect is predefined
> to be a certain bit..  (e.g., AFF_SANCTUARY is (1 << 2) which is the third
> bit).. you can have up to 32 bits if your system is 32 bit ints. (btw, 
> don't take these literally, I don't remember what the actual value of 
> AFF_SANC is, this is just example).  To see if a player is affected by a
> certain affect, you do a bitwise AND:
>  if (ch->affected_by & AFF_SANCTUARY)
>    ...
> This allows for easy checks of multiple affects:
>  if (ch->affected_by & (AFF_1 | AFF_2 | AFF_3))
>    /* will return true if affected_by has any of those bits set */
> 
> The way this would be done with bitfields would be to change the 
> int affected_by to a bitfield:
> 
> #typedef unsigned int us;
> struct affected_by_bitfield {
>   us aff_sanctuary : 1;  /* this field is to take up 1 bit */
>   us aff_hide      : 1;
>   us aff_invis     : 1;
>   ...
> };
> /* in char_data */
>  ...
> struct affected_by_bitfield affected_by;
>  ...
> 
> Then, to test an affect you would do this:
>  if (ch->affected_by.aff_invis)
>  ...
> To check multiple entries, you would use
>  if (ch->affected_by.aff_invis || ch->affected_by.aff_hide)
>    ...
> 
> I realize this would require a complete rewrite of many macros, but there
> are some benefits to this.  One is that you can add an arbitrary number of
> new affects, and if you break 32 you don't have to worry about dealing with
> int affected_by1;
> int affected_by2;
> ...
> Also, you can put in many blanks for future expansion by doing this:
> ...
>  aff_hide : 1
>  extras   : 100
> }
>  then to add a new one, simply:
> ...
>  aff_hide : 1
>  aff_new  : 1
>  extras   : 99  /* pfile is not corrupted */
> }
>  The size of the bitfield in bytes will be the number of bits allocated, 
> divided by 8, rounded up.
> None of this would be visible to the user, but it could make your code more
> structured.

Well, ANSI C doesn't guarantee, that bitfields which extend the size of
an int, are allowed afaik. I guess most compilers will support such a 
feature, but you can't be sure, i never tried it myself.
Though extras: 99 won't be supported by many compilers i guess.

> My question for you more experienced C programmers is, how do you 
think that 
> this would affect efficiency?  I get the feeling that it could actually 
> improve efficiency, as well as produce smaller code.
> For the bitvectors, the operations required to check are this:
> if (ch->affected_by & aff_bit)
>  1. dereference ch pointer
>  2. bitwise AND it with a constant (fast, but also required storage of that
> 	constant in memory)
>  3. test if the result is true
> 
> for bitfield:
> if (ch->affected_by.aff_bit)
>  1. dereference ch pointer
>  2. calculate offset of aff_bit (probably the bottleneck)
>  3. test is result is true
> 
> Is this a correct analysis?  What are other reasons (not) to switch to 
> bitfields?

I wouldn't expect any better efficiency with bitvectors, since most
probably Compilers use internally & and | when accessing bit fields
anyway.  :-)
Though it would be more readable maybe.

Herbert

[on public request 12 lines of signature deleted]  *snip* ;)



This archive was generated by hypermail 2b30 : 12/07/00 PST