如何最小化struct-type的内存使用?

时间:2011-01-10 19:58:21

标签: c++ c memory-management alignment

表示Connect Four的转置表(通常是哈希表) 游戏,我想有效地使用内存(以尽可能多的存储 元素数量)。一个表元素必须存储以下信息:

  • lock:unsigned 64 bit
  • move:[0..6] - >无符号3位
  • 得分:[ - 2000..2000] - >签了12位
  • flag:VALID,UBOUND,LBOUND: - >无符号2位
  • 身高:[ - 1..42]: - >签了7位

首先我尝试了以下数据结构,需要24个字节:

struct TableEntry1
{
    unsigned __int64 lock;
    unsigned char move;
    short score;
    enum { VALID, UBOUND, LBOUND } flag;
    char height;
};

重新排列元素后需要16个字节(我找到了answer 行为):

struct TableEntry2
{
    unsigned __int64 lock;
    enum { VALID, UBOUND, LBOUND } flag;
    short score;
    char height;
    unsigned char move;
};

我的最后一次尝试是:

struct TableEntry3
{
    unsigned __int64 lock;
    unsigned int move:3;
    int score:12;
    enum { VALID, UBOUND, LBOUND } flag:2;
    int height:7;
};

还需要16个字节。是否有可能改变结构 仅使用12个字节(在32位架构上)?为什么编译器不能让我最后一次尝试12个字节?

谢谢!

编辑属性lock是检测哈希冲突的唯一元素ID。

3 个答案:

答案 0 :(得分:6)

是的,因为您只有88位信息,所以可以将其打包成96位(12字节);但是,你真的需要吗?在极端情况下,请记住这样的打包会降低运行时性能。

如果您将这些文件存储到磁盘中,考虑到之前的微小效率会更有意义,但这是这种情况吗?你有没有看过内存使用方面的问题?您需要多少内存,目前有16个字节的对象,以及它与您的计划限制有多接近?尝试在不回答最后两个问题的情况下优化运行时内存使用是premature

除此之外,我怀疑你的编译器在结构的末尾填充,所以__int64总是在8字节边界上对齐。考虑一个长度为2的数组:大小为12字节,最多一个__int64子对象可以是8字节对齐。

答案 1 :(得分:3)

使用非标准构造(如Visual Studio #pragma pack

)可以达到12个字节
#pragma pack(1)
struct TableEntry3
{
    unsigned __int64 lock;
    unsigned int move:3;
    int score:12;
    enum { VALID, UBOUND, LBOUND } flag:2;
    int height:7;
};

在这里,sizeof(TableEntry3)为我产生了12个。

答案 2 :(得分:2)

根据你如何实现锁定,可以减小锁定字段的大小(我假设这是一个典型的SMP锁定SMP机器)

一种选择是减少锁的数量。也就是说,有一个单独的较小的数组锁,并在此处锁定从数组元素派生的元素。也就是说,如果您要访问转置表元素t,请使用锁t % locktablesize。锁定表不必与转置表一样大。

使用这种方法和你的TableEntry2字段顺序,假设你的锁表大小是转置表的一半(可能比必要的大),你可以在不损失性能的情况下减少12个字节由于比特移位操作 - 这种性能损失可能非常显着,因此能够避免这种情况总是有帮助的。