访问一个字节比访问一个位更快吗?为什么?
问题很直接:访问一个字节比访问一个位更快吗?如果我在一个字节中存储 8 个布尔值,当我必须比较它们时,它会比使用 8 个字节慢吗?为什么?
The question is very straight: is it fastest to access a byte than a bit? If I store 8 booleans in a byte will it be slower when I have to compare them than if I used 8 bytes? Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
可能性是没有。当今大多数机器中最小的可寻址内存单元是字节。在大多数情况下,您无法按位寻址或访问。
事实上,访问特定位可能会更加昂贵,因为您必须构建掩码并使用一些逻辑。
编辑:
你的问题提到“比较”,我不确定你的意思到底是什么。但在某些情况下,如果您的布尔值密集地打包为较大的整数类型,则可以使用按位运算符对多个布尔值非常有效地执行逻辑。
至于使用哪种:字节数组(每个字节一个布尔值),或者每个位一个布尔值的密集结构是一种空间效率权衡。对于某些需要存储大量布尔值的应用程序,密集包装更好,因为它可以节省内存。
Chances are no. The smallest addressable unit of memory in most machines today is a byte. In most cases, you can't address or access by bit.
In fact, accessing a specific bit might be even more expensive because you have to build a mask and use some logic.
EDIT:
Your question mentions "compare", I'm not sure exactly what you mean by that. But in some cases, you perform logic very efficiently on multiple booleans using bitwise operators if your booleans are densely packed into larger integer types.
As for which to use: array of bytes (with one boolean per byte), or a densely packed structure with one boolean per bit is a space-effiicency trade-off. For some applications that need to store a massive amount of bools, dense packing is better since it saves memory.
代码运行的底层硬件旨在从内存中访问字节(或更长的字)。要读取一个位,您必须读取整个字节,然后屏蔽掉您不关心的位,并且还可能进行移位以使该位进入到位。因此,访问位的指令是访问字节的指令的超集。
The underlying hardware that your code runs on is built to access bytes (or longer words) from memory. To read a bit, you have to read the entire byte, and then mask off the bits you don't care about, and possibly also shift to get the bit into the ones position. So the instructions to access a bit are a superset of the instructions to access a byte.
出于不同的原因,如果您需要遍历和访问连续的许多 8 位标志集,则将数据存储为位可能会更快。您将为每个布尔标志执行更多操作,但通过将其打包在更少的字节中,您将遍历更少的内存。您还可以在单个操作中测试多个标志,尽管您也可以在某种程度上使用布尔值来执行此操作,只要它们位于单个机器字内即可。
内存延迟损失远高于寄存器位调整。最后,只有在实际运行的硬件上分析代码才能告诉您哪种方式最好。
It may be faster to store the data as bits for a different reason - if you need to traverse and access many 8-bit sets of flags in a row. You will perform more ops per boolean flag, but you will traverse less memory by having it packed in fewer bytes. You will also be able to test multiple flags in a single operation, although you may be able to do this with bools to some extent as well, as long as they lie within a single machine word.
The memory latency penalty is far higher than register bit twiddling. In the end, only profiling the code on the hardware on which it will actually run will tell you which way is best.
从硬件的角度来看,我想说,一般情况下,最好情况下的所有位掩码和其他操作都可能发生在单个时钟内(结果没有什么不同),但这完全取决于您可能不会的硬件层永远不知道细节,因此你不能指望它。
值得指出的是,像 .NET
system.collections.bitarray
这样的东西在下面使用一个 32 位整数数组来存储它的位数据。此实现背后可能存在性能原因(即使仅在一般情况下 32 位字的性能高于平均水平),我建议阅读其内部工作原理,这可能会有所启发。从编码的角度来看,这实际上取决于您之后要如何处理这些位。也就是说,如果您要将数据存储在布尔值中,例如:
然后在代码中将它们一一比较(并且大多数都在一起):
那么您会发现它会更快(并且可能更整洁)在代码中)使用位掩码。但实际上,唯一重要的是,如果您要在高性能或时间关键的环境中运行此代码数百万次。
我想我在这里得到的是,你应该按照你的编码标准所说的去做(如果你没有任何编码标准,或者他们不考虑这些细节,那么就做看起来最适合你的应用程序和需要的事情)。
但我强烈建议尝试四处看看并阅读一两篇博客,解释 .NET
system.collections.bitarray
的内部工作原理。From a hardware point of view, I would say that in general all the bit masking and other operations in the best case might occur within a single clock (resulting in no different), but that entirely depends on hardware layer that you likely won't ever know the specifics of, and as such you cannot bank on it.
It's worth pointing out that things like the .NET
system.collections.bitarray
uses a 32bit integer array underneath to store it's bit data. There is likely a performance reason behind this implementation (even if only in a general case that 32bit words perform above average), I would suggest reading up about the inner workings of that might be revealing.From a coding point of view, it really depends what you're going to do with the bits afterwards. That is to say if you're going to store your data in booleans such as:
And then in your code you compare them one by one (and most of them together):
Then you will find that it will be faster (and likely neater in code) to use a bit mask. But really the only time this would matter is if you're going to be running this code millions of times in a high performance or time critical environment.
I guess what I'm getting at here is that you should do whatever your coding standards say (and if you don't have any or they don't consider such details then just do what looks neatest for your application and need).
But I highly suggest trying to look around and read a blog or two explaining the inner workings of the .NET
system.collections.bitarray
.这取决于处理器和主板数据总线的类型,即如果您将数据收集到“word”而不是“bool”或“byte”中,32位数据总线会更快地比较您的数据......
仅当您用汇编语言编写时,这才有效,当您可以比较每条指令需要多少个周期时......但由于您使用的是编译器,所以它几乎是相同的。
但是,将布尔值收集为字或整数对于节省变量所需的内存非常有用。
This depends on the kind of processor and motherboard data bus, i.e. 32 bit data bus will compare your data faster if you collect them into "word"s rather than "bool"s or "byte"s....
This is only valid when you are writing in assembly language when you can compare each instruction how many cycles it takes .... but since you are using compiler then it is almost the same.
However, collecting booleans into words or integers will be useful in saving memory required for variables.
计算机倾向于用文字来访问事物。访问一点会比较慢,因为它需要更多的努力:
想象一下我对你说了些什么,然后说“哦,把我的第二个词改为”。
现在想象我的编辑是“哦,将第二个单词中的第三个字母更改为“s””。
哪一个需要你更多的思考?
Computers tend to access things in words. Accessing a bit is slower because it requires more effort:
Imagine I said something to you, then said "oh change my second word to instead".
Now imagine my edit instead was "oh, change the third letter in the second word to 's'".
Which requires more thinking on your part?