我试图尽可能地挤出我的记忆。
我有一个4.9999995e13
整数的矩阵,但它们只需要是真或假 - 基本上我只需要为这些整数中的每一个存储一点。
我知道C中没有单一的位类型(也许有人可以解释为什么,对我而言),而且我也知道如果存在short short int
,它将是1字节,与char相同。但是,C中的所有逻辑运算都返回整数(以及一些其他函数)。
所以我的问题是:
short short int
存在?char
代替,那么我是否会因为int
所有必须完成的演员而降低演奏效果?只是在案件中它是相关的,我正在用GCC编译C99。
编辑我刚刚在this wikipedia page看到有_Bool
类型,这实际上是标准吗?
答案 0 :(得分:6)
__Bool
类型是最新版本的C中的标准类型,但仍然不是您想要的类型,因为__Bool
仍占用至少一个字节(char
也是如此根据定义)。
不,如果你想要那么多布尔位,你需要将它们打包成bitfield或bit array。 C中的位域没有标准数据类型,因此您还必须编写自己的宏或函数来获取特定偏移量的位。我也希望你能在拥有大量内存的64位机器上运行它,否则你的内存耗尽会快。
答案 1 :(得分:5)
你想要的是位图(或维基百科称之为bit array)。
并且没有short short int
这样的东西,它只是char
,它是C中最小的整数存储类。
使用这种方法时可能会有一些性能开销,但不是因为对int的隐式转换,而是因为操作位图比直接操作数组成员更棘手。
一个小例子可能有助于说明:
使用普通整数矩阵:
int mat[8*8]; // assuming row major order int is_element_set(int x, int y) { return mat[y*8 + x]; }
使用位图:
unsigned char mat[8]; // assuming CHAR_BIT == 8
int is_element_set(int x, int y) {
return mat[y] & (1 << x);
}
答案 2 :(得分:4)
您有大约50太比特的数据。你想一次将它们全部装入RAM中吗?在orrder中使用多于一点的RAM来保存一点信息是完全疯狂的,即便如此,你的计算机也必须与这个星球上最大的超级计算机大小相当。忘记位打包的性能。你将不得不担心完全不同的事情。
答案 3 :(得分:3)
5e13,大约需要5.6 TB的存储空间,只需要代表你的位域。可能有更好的方法来处理你的问题。
答案 4 :(得分:1)
也许你可以使用ANSI C中可用的位字段结构的一些明智的实现。
这样的事情:
typedef struct node_t_
{
char bit0 : 1;
char bit1 : 1;
char bit2 : 1;
char bit3 : 1;
char bit4 : 1;
char bit5 : 1;
char bit6 : 1;
char bit7 : 1;
} node_t;
然后,您可以制作一些快速函数(可能是宏)来获取和设置此矩阵中的元素。不过,我还没有实现过这样的东西。
答案 5 :(得分:1)
C99 stdbool.h
允许使用bool
。不过这里你的问题是4.9999995e13 / 8会提供更多或更少的6.2500e + 12($ 10 ^ 9 $是Gbyte,$ 10 ^ 12 $是Tbyte),所以你需要超过6TB的真实+虚拟内存(需要幸运)。这表明你做错了什么。您需要在可以使用较少内存处理的子问题中“缩放”您的问题。
答案 6 :(得分:1)
正如其他人所建议的那样,你应该使用一个位域。
此外,如果您只是使用true / false值,并且其中一个值比另一个值少得多,请考虑使用隐式编码。您可以使用地图数据结构轻松完成此任务。当您正在使用图表时,如果您的图表完全稀疏,这将为您节省大量内存。如果将其与上面的位打包技术结合使用,您甚至可以将其全部放入RAM中。必须非常聪明的索引。
你可以做的另一件事,如果你不关心在处理过程中遇到性能损失(即如果你更担心存储它而不是处理它),那就是运行结构通过块中的压缩算法。有一个bzip2的C库,可以为你节省90%或更多。缺点是这需要(很长时间)。你可以通过动态马尔可夫压缩(DMC)这样的按位压缩器获得相当的性能,而且速度要快得多。
答案 7 :(得分:0)
我正试图尽可能地挤出我的记忆。
如果这是真的,那么你不会浪费8位来存储1位数据。你会使用一个位域。
如果你对矩阵所具有的内容有所了解,那么你可以使用其他优化。例如,如果您知道矩阵的绝大部分通常设置为零,那么您只能存储设置为1的x,y对元素。
如果没有,则4.9999995e13将占用大约6 TB的RAM!