gpt4 book ai didi

c - 有什么方法可以在位集中表示约 27 个整数并有效地访问它们吗?

转载 作者:太空宇宙 更新时间:2023-11-03 23:37:05 25 4
gpt4 key购买 nike

我有一个包含 27 个有符号整数的数组的结构。这个结构在打包字节后大约需要 112 字节的内存。我想减小结构的大小。由于这些整数不能大于 400k,我只需要 20 位来表示它们。我浪费了大量的内存,因为我需要很多这样的结构。有什么方法可以降低内存成本,同时仍然能够访问每个 int 而不会造成太多性能损失?实现 bitset 是最好的方法吗?

最佳答案

是的,这叫做位打包,虽然位集可能不是表达它的正确方式。位集(至少在 C++ 和 Java 中)占用的空间比数据位多,这违背了您的目的。

相反,在 C 中,您可以使用位域 或自行调整位。位域是结构中具有指定位大小的元素。它们专门设计用于节省空间。但是在您的情况下,这种方法有两个问题:

  1. 鉴于您的字段相对较大(20 位),它们可能不会像您希望的那样打包。与单词边界相关的一些选择是 implementation defined ,因此您可能会发现编译器最终还是浪费了太多空间。
  2. 位字段不允许使用数组,因此指定 27 个单独的字段可能很麻烦。

所以我建议你自己做。只需将您的数组声明为 27*20/8(向上舍入)字节数组:

#define ROUND_UP(n,d) (((n) + (d) - 1) / (d));
unsigned char myPackedIntArray[ROUND_UP(27*20,8)];

然后写一个getter和一个setter:

int unpack(unsigned char packedArray[], int index)
{
struct {signed int i:20;} res; //handy way to do the sign extension from 20 bits to int width.
int byteIndex = index*20 / 8;
if(index%2 == 0) //even 20-bit fields start on a byte boundary
{
res.s = (packedArray[byteIndex ]<<12);
res.s += (packedArray[byteIndex+1]<<4);
res.s += (packedArray[byteIndex+2]>>4);
}
else //odd 20-bit fields start halfway through the byte
{
res.s = ((packedArray[byteIndex ]&0x0F) << 16);
res.s += ((packedArray[byteIndex+1] ) << 8);
res.s += ((packedArray[byteIndex+2] );
}

return (int)(res.s);
}

int pack(unsigned char packedArray[], int index)
{
//left as exercise to the reader
}

将 20 位值打包和解包到一个紧密打包的数组中。

现在谈到性能问题 - 查看 getter 和 setter 会给您一个好主意。取一次取,而不是一次乘法和除法,取 3 次取和一些位操作。 Dan Lemire在这个话题上有一些很好的结果。简短的回答是“不会更糟”,但最终这将与您的编译器和架构有很大关系。

关于c - 有什么方法可以在位集中表示约 27 个整数并有效地访问它们吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57542560/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com