在c++中,

为什么布尔值是1字节而不是1位? 为什么没有4位或2位整数类型?

在为CPU编写模拟器时,我忽略了上述内容


因为CPU不能寻址任何小于字节的东西。


最简单的答案是;这是因为CPU以字节而不是位来寻址内存,按位的操作非常慢。

然而,在c++中可以使用位分配。对于位向量,有std::vector专门化,还有接受位大小条目的结构。


你可以有1位的bool型和4位和2位的int型。但这将导致一个奇怪的指令集,没有性能提升,因为这是一种不自然的方式来看待体系结构。“浪费”一个字节的大部分,而不是试图回收未使用的数据,实际上是有意义的。

根据我的经验,唯一一个把几个bool包进一个字节的应用程序是Sql Server。


因为字节是语言中最小的可寻址单位。

但是你可以让bool值为1位,如果你有很多 如。在结构体中,像这样:

struct A
{
  bool a:1, b:1, c:1, d:1, e:1;
};

因为在一般情况下,CPU以1字节作为基本单位分配内存,尽管一些CPU如MIPS使用4字节字。

但是vector以一种特殊的方式处理bool类型,vector<bool>为每个bool类型分配一个位。


字节是计算机中数字数据存储的较小单位。在计算机中,RAM有数百万个字节,每个字节都有一个地址。如果每个比特都有一个地址,那么计算机就可以少管理8倍的内存。

更多信息:维基百科


您可以使用位字段来获取子大小的整数。

struct X
{
    int   val:4;   // 4 bit int.
};

尽管它通常用于将结构映射到精确的硬件预期位模式:

// 1 byte value (on a system where 8 bits is a byte)
struct SomThing   
{
    int   p1:4;   // 4 bit field
    int   p2:3;   // 3 bit field
    int   p3:1;   // 1 bit
};

从维基百科:

从历史上看,字节是的数字 用于编码单个字符的位 电脑里的文本,的确如此 因此,基本可寻址 许多计算机中的元件 架构。

因此字节是基本的可寻址单位,低于它计算机体系结构不能寻址。由于(可能)不存在支持4位字节的计算机,所以没有4位bool等。

然而,如果你可以设计这样一个体系结构,它可以将4位作为基本可寻址单位,那么你将拥有大小为4位的bool值,只在那台计算机上!


bool can be one byte -- the smallest addressable size of CPU, or can be bigger. It's not unusual to have bool to be the size of int for performance purposes. If for specific purposes (say hardware simulation) you need a type with N bits, you can find a library for that (e.g. GBL library has BitSet<N> class). If you are concerned with size of bool (you probably have a big container,) then you can pack bits yourself, or use std::vector<bool> that will do it for you (be careful with the latter, as it doesn't satisfy container requirments).


Back in the old days when I had to walk to school in a raging blizzard, uphill both ways, and lunch was whatever animal we could track down in the woods behind the school and kill with our bare hands, computers had much less memory available than today. The first computer I ever used had 6K of RAM. Not 6 megabytes, not 6 gigabytes, 6 kilobytes. In that environment, it made a lot of sense to pack as many booleans into an int as you could, and so we would regularly use operations to take them out and put them in.

今天,当人们嘲笑你只有1gb的RAM,而你唯一能找到小于200gb的硬盘的地方是在古董店,它只是不值得麻烦打包比特。


考虑一下如何在模拟器级别实现这一点……

bool a[10] = {false};

bool &rbool = a[3];
bool *pbool = a + 3;

assert(pbool == &rbool);
rbool = true;
assert(*pbool);
*pbool = false;
assert(!rbool);

即使最小大小可能是1字节,你可以在1字节上有8位布尔信息:

http://en.wikipedia.org/wiki/Bit_array

Julia语言有BitArray,我读过c++实现。


位操作并不“慢”。

和/或操作往往很快。

问题是对齐和解决它的简单问题。

cpu作为部分正确回答的答案通常与读取字节对齐,RAM/内存也以同样的方式设计。

因此,为了使用更少的内存空间,必须显式地对数据压缩进行排序。

As one answer suggested, you could order a specific number of bits per value in a struct. However what does the CPU/memory do afterward if it's not aligned? That would result in unaligned memory where instead of just +1 or +2, or +4, there's not +1.5 if you wanted to use half the size in bits in one value, etc. so it must anyway fill in or revert the remaining space as blank, then simply read the next aligned space, which are aligned by 1 at minimum and usually by default aligned by 4(32bit) or 8(64bit) overall. The CPU will generally then grab the byte value or the int value that contains your flags and then you check or set the needed ones. So you must still define memory as int, short, byte, or the proper sizes, but then when accessing and setting the value you can explicitly compress the data and store those flags in that value to save space; but many people are unaware of how it works, or skip the step whenever they have on/off values or flag present values, even though saving space in sent/recv memory is quite useful in mobile and other constrained enviornments. In the case of splitting an int into bytes it has little value, as you can just define the bytes individually (e.g. int 4Bytes; vs byte Byte1;byte Byte2; byte Byte3; byte Byte4;) in that case it is redundant to use int; however in virtual environments that are easier like Java, they might define most types as int (numbers, boolean, etc.) so thus in that case, you could take advantage of an int dividing it up and using bytes/bits for an ultra efficient app that has to send less integers of data (aligned by 4). As it could be said redundant to manage bits, however, it is one of many optimizations where bitwise operations are superior but not always needed; many times people take advantage of high memory constraints by just storing booleans as integers and wasting 'many magnitudes' 500%-1000% or so of memory space anyway. It still easily has its uses, if you use this among other optimizations, then on the go and other data streams that only have bytes or few kb of data flowing in, it makes the difference if overall you optimized everything to load on whether or not it will load,or load fast, at all in such cases, so reducing bytes sent could ultimately benefit you alot; even if you could get away with oversending tons of data not required to be sent in an every day internet connection or app. It is definitely something you should do when designing an app for mobile users and even something big time corporation apps fail at nowadays; using too much space and loading constraints that could be half or lower. The difference between not doing anything and piling on unknown packages/plugins that require at minumim many hundred KB or 1MB before it loads, vs one designed for speed that requires say 1KB or only fewKB, is going to make it load and act faster, as you will experience those users and people who have data constraints even if for you loading wasteful MB or thousand KB of unneeded data is fast.