我无法理解为什么这个结构占用了96个字节的ram。
struct cell
{
bool filled;
bool isParent;
short int mat;
bool cx,cy,cz;
vect norm;
struct cell* child[8];
struct cell* parent;
cell(float pxx=0, float pyy=0, float pzz=0, float ss=0, cell *par=NULL, bool cxx=0, bool cyy=0, bool czz=0);
void open_read(string);
};
我知道单词allignment,但这应该至少不超过64字节,我认为...... 这个结构将有数百万个实例,那么我怎样才能将内存占用降到最低? 我正在使用linux和vect是一个向量(3个浮点数)
答案 0 :(得分:1)
你的指针并不多。
但是,您可以使用单位枚举器或位域将所有布尔值缩减为单个字节。根据{{1}}的最大值,您可以将标志和该值压缩为两个字节。这不是一个很大的节省。
如果您希望您的树非常密集,您可以通过将您的孩子分配为池来获得显着收益。也就是说,你有一个mat
指针,它引用一个内存块,它是一个包含所有八个子节点的数组。然后你保存每条记录7个指针的空间,理解每个非叶子节点将分配比它需要更多的内存。你可能需要一个标志来表明节点是空的。
或者,如果要牺牲数组的随机访问权限,可以将子项链接为列表。然后你只需要一个struct cell* child
指针和一个child
指针。每个节点节省6个指针,没有浪费。虽然它有点吝啬。
答案 1 :(得分:1)
问题显然是64位系统上的8字节指针
如果你真的想尽量减少内存占用,并且你愿意跳舞以实现它,我们可以尝试减少指针大小
建议不要移动到32位指针,因为那时你只能访问4 GB的ram,如果你耗尽了大量的内存,这可能还不够
我可以建议这种有点疯狂的方法:
对于您的结构,请使用自定义分配器而不是常规堆。自定义分配器基本上意味着对于此特定结构的实例,您使用自己管理的单独堆。在Windows操作系统上,使用HeapCreate()非常容易,在Linux上,使用此问题引用的mmap:HeapCreate, HeapAlloc in Linux, private allocator for Linux
由于我们为此结构类型提供了一个单独的堆,因此该堆只会分配和释放此结构的实例。这本身就是一个很大的优化,因为所有大小完全相同的分配都会消除堆碎片。
现在,为了这个伎俩。由于每个实例都在这个单独的堆中,我们可以给它一个索引。只需获取其分配的指针,减去堆起始指针并除以结构大小。堆中的第一个结构将获得索引0,第二个结构是索引1,依此类推。我们要做的是保存struct的索引而不是指向struct的指针。这些索引的空间效率更高,可以很容易地转换回指针。
这种方法当然只会最小化指向单元格结构的指针。不是通用堆中的通用指针。如果您认为除以结构大小是危险的(假设所有结构在堆中都是连续的),只需跳过此步骤,它只会节省几个位。简单地构建堆启动可能足以为您节省大量空间。
有点矫枉过正,但有趣的是:)
答案 2 :(得分:0)
Talkol建议使用自定义分配器是一个很好的建议。如果以随机顺序访问结构并且您对实现最佳性能感兴趣,那么工作可能是好的,因此您的结构正好是字节,并且在64字节边界上对齐。数据以64字节的块称为“行”从主存中提取到高速缓存中; CPU可以在从主存储器中获取块到缓存所需的时间内执行数十或数百条指令。如果以随机顺序访问结构,将它们对齐将意味着读取每个结构将只需要加载一个缓存行而不是两个。
请注意,如果有时会按顺序访问数据,则较小的结构可以提高效率,因为即使访问一个需要获取两个缓存行,访问下一个也需要最多获取一个;如果一个结构占用48个字节,则每组访问的四个结构只需要三次高速缓存行提取,但随机访问平均需要1.5个高速缓存行提取。