Bit field efficiency

P

Philipp

Hello,

I have a class Position which declares a bit field
class Position{
public:
Position(int i=0, int j=0, int k=0);
// Positions have to be within the range: [0..8191,0..8191,0..7]
void setPosition(int i, int j, int k);
int getI();
int getJ();
int getK();
friend ostream& operator<< (ostream& outs, const Position &rhs);
private:
unsigned short i:13;
unsigned short j:13;
unsigned short k:3;
};

How efficient is this technique to save memory (I have a lot of Position
objects)? What size of memory will the three vars i,j,k really occupy in
the memory?

Does this depend on the compiler (icc 7.1 on linux)? On the architecture
(i686)?

Thanks for answers
Phil
 
V

Victor Bazarov

Philipp said:
I have a class Position which declares a bit field
class Position{
public:
Position(int i=0, int j=0, int k=0);
// Positions have to be within the range:
[0..8191,0..8191,0..7] void setPosition(int i, int j, int k);
int getI();
int getJ();
int getK();
friend ostream& operator<< (ostream& outs, const Position
&rhs); private:
unsigned short i:13;
unsigned short j:13;
unsigned short k:3;
};

How efficient is this technique to save memory (I have a lot of
Position objects)?

Compared to what?
What size of memory will the three vars i,j,k
really occupy in the memory?
sizeof(Position)

Does this depend on the compiler (icc 7.1 on linux)? On the
architecture (i686)?

No doubt.

V
 
M

Michael DOUBEZ

Philipp a écrit :
Hello,

I have a class Position which declares a bit field
class Position{
public:
Position(int i=0, int j=0, int k=0);
// Positions have to be within the range: [0..8191,0..8191,0..7]
void setPosition(int i, int j, int k);
int getI();
int getJ();
int getK();
friend ostream& operator<< (ostream& outs, const Position &rhs);
private:
unsigned short i:13;
unsigned short j:13;
unsigned short k:3;
};

How efficient is this technique to save memory (I have a lot of Position
objects)? What size of memory will the three vars i,j,k really occupy in
the memory?

You have to try on your architecture with your compiler. If you are on a
32bits architecture I would say you should reasonably be able to pack
everything in 32bits.

Perhaps reordering will save some alignement issue:
unsigned short i:13;
unsigned short k:3;
//13+3=16 bits aligned
unsigned short j:13;
//3 bits padding

Does this depend on the compiler (icc 7.1 on linux)? On the architecture
(i686)?

From 9.6 of the standard (N2135 in fact):
Allocation of bit-fields within a class object is
implementation-defined. Alignment of bit-fields is
implementation-defined. Bit-fields are packed into some addressable
allocation unit. [Note: bit-fields straddle allocation
units on some machines and not on others. Bit-fields are assigned
right-to-left on some machines,left-to-right on others.
—end note]
 
P

Philipp

Michael DOUBEZ a écrit :
Philipp a écrit :
Hello,

I have a class Position which declares a bit field
class Position{
public:
Position(int i=0, int j=0, int k=0);
// Positions have to be within the range: [0..8191,0..8191,0..7]
void setPosition(int i, int j, int k);
int getI();
int getJ();
int getK();
friend ostream& operator<< (ostream& outs, const Position &rhs);
private:
unsigned short i:13;
unsigned short j:13;
unsigned short k:3;
};

How efficient is this technique to save memory (I have a lot of
Position objects)? What size of memory will the three vars i,j,k
really occupy in the memory?

You have to try on your architecture with your compiler. If you are on a
32bits architecture I would say you should reasonably be able to pack
everything in 32bits.

Perhaps reordering will save some alignement issue:
unsigned short i:13;
unsigned short k:3;
//13+3=16 bits aligned
unsigned short j:13;
//3 bits padding

Thanks for your answer. I will look into the alignment issue. I'm
surprised that the compiler would not rearrange this so as to be optimal.

Phil
 
J

James Kanze

I have a class Position which declares a bit field
class Position{
public:
Position(int i=0, int j=0, int k=0);
// Positions have to be within the range: [0..8191,0..8191,0..7]
void setPosition(int i, int j, int k);
int getI();
int getJ();
int getK();
friend ostream& operator<< (ostream& outs, const Position &rhs);
private:
unsigned short i:13;
unsigned short j:13;
unsigned short k:3;
};
How efficient is this technique to save memory (I have a lot of Position
objects)? What size of memory will the three vars i,j,k really occupy in
the memory?

It depends somewhat on the implementation, but at the very
least, the last two should pack into a single 16 element; if the
size of an int is more than 29 bits, they should all pack into a
single int. On a machine with 8 bit bytes and byte addressing,
I would expect 4 bytes for the lot; without the bit fields, 6,
or possibly even 8 bytes. So you gain some memory; where bit
fields really start gaining memory, of course, is when you have
a lot of one or two bit fields.

You don't get anything for free, however. Accessing bit-fields
is considerably slower than accessing ints. In some cases, this
can be offset by improved locality; you get more elements in
each page and/or cache line. Most of the time, however,
bit-fields have a very negative impact on run-time. (Note that
writing to a bit-field will normally require two accesses, a
read and a write.)
Does this depend on the compiler (icc 7.1 on linux)? On the architecture
(i686)?

Somewhat. In practice, there's a pretty widespread concensus as
to what is "best practice" for "conventional" architectures, and
the comments above will almost certainly be valid for most, if
not all, mainstream compilers and machines today, and even for
most exotics. The exact layout of the bit-fields will vary,
however.
 
E

Ehud Shapira

If you want to be sure it's packed as much as possible, why not set
the bits directly yourself?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,200
Latest member
LaraHunley

Latest Threads

Top