【问题标题】:Fastest ways to set and get a bit最快的方法来设置和获得一点
【发布时间】:2011-05-21 19:38:02
【问题描述】:

我只是在尝试开发超快速函数来设置和获取 uint32 数组中的位。例如,您可以说“将位 1035 设置为 1”。然后,以 1035 / 32 为索引的 uint32 与位位置 1035 % 32 一起使用。我特别不喜欢 setbit 函数中的分支。

这是我的方法:

void SetBit(uint32* data, const uint32 bitpos, const bool newval)
{
   if (newval)
   {
      //Set On
      data[bitpos >> 5u] |= (1u << (31u - (bitpos & 31u)));
      return;
   }
   else
   {
      //Set Off
      data[bitpos >> 5u] &= ~(1u << (31u - (bitpos & 31u)));
      return;
   }
}

bool GetBit(const uint32* data, const uint32 bitpos)
{
   return (data[bitpos >> 5u] >> (31u - (bitpos & 31u))) & 1u;
}

谢谢!

【问题讨论】:

  • 什么架构?什么语言?编译器现在输出什么?您可能会发现它已经相当快了。
  • 它是 x86(32 位)。确实,它已经相当快了,但我认为——尤其是在 setbit 函数中,我仍然可以更快......
  • 您的 SetBit 看起来确实是一个 FlipBit,因为您可能只使用 xor(通常是 ~= 运算符)。
  • 它不是 FlipBit,因为您可以将位设置为独立于先前状态的固定定义状态。

标签: bit operations bitset


【解决方案1】:

首先,我会从所有表达式中删除31u - ...:它所做的只是对位集的私有表示中的位重新排序,因此您可以在没有任何人注意的情况下翻转此顺序。

其次,您可以使用clever bit hack 摆脱分支:

void SetBit(uint32* data, const uint32 bitpos, const bool f)
{
    uint32 &w = data[bitpos >> 5u];
    uint32 m = 1u << (bitpos & 31u);
    w = (w & ~m) | (-f & m);
}

第三,您可以通过让编译器进行转换来简化您的 getter:

bool GetBit(const uint32* data, const uint32 bitpos)
{
    return data[bitpos >> 5u] & (1u << (bitpos & 31u));
}

【讨论】:

    猜你喜欢
    • 2017-05-16
    • 2022-12-24
    • 1970-01-01
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多