繁体   English   中英

C / C ++位域与按位运算符相比,可以更快,更好,更便携地选择位?

[英]C/C++ bitfields versus bitwise operators to single out bits, which is faster, better, more portable?

我需要以这种方式在字节中打包一些位:

struct  
{  
  char bit0: 1;  
  char bit1: 1;  
} a;  

if( a.bit1 ) /* etc */

要么:

if( a & 0x2 ) /* etc */

从源代码的清晰性来看,对我来说很明显位域更整洁。 但是哪个选择更快? 我知道速度差异不会太大,但是我可以使用其中的任何一个,如果速度更快,更好。
另一方面,我读到不能保证位域在平台之间以相同顺序排列位,并且我希望代码具有可移植性。

注意:如果您打算回答“个人资料”,可以,我会的,但是由于我很懒,如果有人已经有了答案,那就更好了。
代码可能是错误的,如果需要,您可以纠正我,但请记住此问题的重点,也请尝试回答。

如果位域使用得当,它们会使代码更清晰。 我只会将位域用作节省空间的设备。 我见过它们使用的一个常见地方是在编译器中:类型或符号信息通常由一堆true / false标志组成。 位域在这里是理想的,因为典型程序在编译时会创建成千上万个这样的节点。

我不会使用位域来完成常见的嵌入式编程工作:读取和写入设备寄存器。 我更喜欢在这里使用shift和mask,因为您可以准确地得到文档告诉您的所需位,而不必担心各种编译器在实现位域方面的差异。

至于速度,一个好的编译器将为位域提供与屏蔽相同的代码。

为了获得最大的可移植性,我宁愿使用第二个示例。 正如尼尔·巴特沃思(Neil Butterworth)所指出的那样,仅对本机处理器使用位域。 好了,想想看,如果英特尔的x86明天停产,代码将被卡住,这意味着必须重新实现另一个处理器的位域,如RISC芯片。

您必须从更大的角度看,并问OpenBSD如何使用一个代码库将其BSD系统移植到许多平台上? 好的,我承认这有点过头了,值得商and和主观,但实际上,如果您要将代码移植到另一个平台,则可以使用问题中使用的第二个示例来实现。 。

不仅如此,针对不同平台的编译器将具有自己的填充方式,将编译器所在的处理器的位字段对齐。 而且,处理器的耐久性如何?

永远不要把位域当作魔术子弹。 如果您想要处理器的速度并将其固定在其上,即无意移植,则可以随意使用位域。 不能同时拥有!

由于未知的原因,C位字段从被发明的那一刻就诞生了。 人们不喜欢它们,而是使用按位运算符。 您必须期望其他开发人员不了解C位域代码。

关于哪个更快:不相关。 任何优化的编译器(实际上是所有编译器)都会使代码以任何表示方式执行相同的操作。 对于C程序员来说,一个普遍的误解是编译器只是将关键字搜索并替换为汇编语言。 现代编译器将源代码用作要实现的目标的蓝图,然后发出通常看起来非常不同但可以达到预期结果的代码。

第一个是显式的,无论第二个表达式的速度如何,都容易出错,因为对结构的任何更改都可能使第二个表达式错误。

因此,请使用第一个。

如果要携带,请避免使用位域。 而且,如果您对特定代码的性能感兴趣,那么除了编写自己的测试之外别无选择。 记住,位域将在后台使用处理器的按位指令。

我认为C程序员倾向于使用位掩码和逻辑运算来推断每个位的值的第二种选择。 可以使用枚举来设置枚举,或者通常在涉及更复杂的操作时使用宏来获取/设置特定位,而不是用十六进制值来填充代码。 我听说过,实现结构的位域速度较慢。

在“非便携式位域”中不要读太多。 位域有两个方面,它们是实现定义的:有符号性和布局,一个未指定的域:打包它们的分配单元的对齐方式。 如果您不需要打包效果,使用它们就像函数调用一样具有可移植性(只要您在需要的地方明确指定一个带signed关键字),这些函数也具有未指定的属性。

关于性能,配置文件是您可以获得的最佳答案。 在一个完美的世界中,这两种著作之间没有区别。 实际上,可以有一些原因,但是我可以想到一个方向上与另一个方向上一样多的原因。 而且它可能对上下文非常敏感(例如,无符号和有符号之间在逻辑上无意义的差异),因此请在上下文中进行测量...

综上所述,因此,在您真正有选择权的情况下,差异主要是样式差异(即,如果精确的布局很重要则不是)。 在那种情况下,这是一种优化(大小,而不是速度),因此我倾向于先编写没有代码的代码,然后在需要时添加它。 因此,位字段是显而易见的选择(要做的修改是获得结果的最小修改,并且包含在定义的唯一位置,而不是扩展到所有使用位置)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM