for the transposition table (generally a hash table) of a Connect Four
game, I would like to use the memory efficiently (to store the most possible
number of elements). One table element has to store following information:
- lock: unsigned 64 bit
- move: [0..6] –> unsigned 3 bit
- score: [-2000..2000] –> signed 12 bit
- flag: VALID, UBOUND, LBOUND: –> unsigned 2 bit
- height: [-1..42]: –> signed 7 bit
First I tried following data structure, which needs 24 Bytes:
struct TableEntry1
{
unsigned __int64 lock;
unsigned char move;
short score;
enum { VALID, UBOUND, LBOUND } flag;
char height;
};
After rearranging the elements it needs 16 Bytes (I found the answer for this
behavior):
struct TableEntry2
{
unsigned __int64 lock;
enum { VALID, UBOUND, LBOUND } flag;
short score;
char height;
unsigned char move;
};
My last try was:
struct TableEntry3
{
unsigned __int64 lock;
unsigned int move:3;
int score:12;
enum { VALID, UBOUND, LBOUND } flag:2;
int height:7;
};
Which also needs 16 Bytes. Is it possible to change the structure so that it
only uses 12 Bytes (on a 32 bit-architecture)? Why the compiler doesn’t make my last try 12 bytes long?
Thanks!
Edit The property lock is a unique element id to detect hash collisions.
Depending on how you implement locks, it may be possible to reduce the size of your lock field (I’m assuming this is a typical SMP lock SMP machine)
One option would be to reduce the number of locks. That is, have a seperate, smaller array of locks, and lock an element derived from your array element here. That is, if you’re accessing transposition table element
t, use lockt % locktablesize. The lock table doesn’t have to be nearly as big as the transposition table.Using this approach, and your
TableEntry2field order, and assuming your lock table is half the size of the transposition table (which is probably bigger than necessary) you get down to 12 bytes without losing performance due to bitshift operations – this performance loss can be quite significant, so it’s always helpful to be able to avoid it.