11

我有一个 C++ 应用程序,其中包含许多带有手动控制位字段的结构,例如

#define FLAG1   0x0001  
#define FLAG2   0x0002      
#define FLAG3   0x0004      

class MyClass
{
'
'
  unsigned Flags;

  int IsFlag1Set() { return Flags & FLAG1; }
  void SetFlag1Set() { Flags |= FLAG1; }
  void ResetFlag1() { Flags &= 0xffffffff ^ FLAG1; }
'
'
};

出于显而易见的原因,我想将其更改为使用位字段,例如

class MyClass
{
'
'
  struct Flags
  {
    unsigned Flag1:1;
    unsigned Flag2:1;
    unsigned Flag3:1;
  };
'
'
};

进行此切换时我担心的一个问题是,我在该站点上遇到了许多参考资料,说明了 C++ 中位字段的速度有多慢。我的假设是它们仍然比上面显示的手动代码更快,但是是否有任何硬参考材料涵盖在各种平台上使用位字段的速度影响,特别是 32 位和 64 位窗口。该应用程序处理内存中的大量数据,并且必须既快速又高效,这很可能是它最初以这种方式编写的原因。

4

3 回答 3

6

这两个示例的速度应该非常相似,因为编译器最终必须在两种情况下发出几乎相同的位掩码指令。要知道哪个是最好的,请进行一些简单的实验。但是,如果结果不确定,请不要感到惊讶;这就是我预测的...

你可能会更好地说位域是类型的bool

于 2010-04-14T14:15:46.597 回答
5

除非这是在一个非常非常紧凑的循环中,否则如果性能真的很重要,则在两者之间没有什么可以选择的性能,使用布尔值(即可能是 32 位值)。

使用只有三个像这样的单个位字段的结构仍然会填充到至少32 位。如果您绝对专注于保存所有可能的内容,请查看编译器关于结构对齐和填充的文档。

编辑:偏爱位域的一个原因是它们使代码更整洁,并且不应低估可维护性的重要性。与程序员时间相比,计算机时间便宜!

于 2010-04-14T14:16:11.820 回答
2

针对此类问题的一般建议:设置一个简单的程序,尽可能准确地比较您的情况(操作、硬件等),并自己衡量您的性能差异。

For this question on bitfields vs masking, I doubt you'll see significant performance differences - the bitfield code may need a shift or two more than masking, depending on the compiler. Whether that's noticeable in your application or not is something you need to answer. There's a big difference in the considerations for mask-programmable embedded code vs. desktop applications, for example.

于 2010-04-14T14:28:11.787 回答