最快的方法来设置和获得一点

Posted

技术标签:

【中文标题】最快的方法来设置和获得一点【英文标题】: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,因为您可以将位设置为独立于先前状态的固定定义状态。 【参考方案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));

【讨论】:

以上是关于最快的方法来设置和获得一点的主要内容,如果未能解决你的问题,请参考以下文章

在本地安装和设置 TYPO3 的最快方法是啥?

有没有更好的方法(最快)来获得最长的公共文件夹路径?

斐讯路由器K1刷机到华硕 RT-AC54U界面,求怎么设置网速最快最稳定。在线

如何设置ffmpeg使得转码最快

使 UIView 或 CALayer 变暗的最快方法(性能方面)

针对 MS Access DB 设置此 asp.net 页面的最快方法。 .