设置和获取位的最快方法

发布于 2024-10-06 08:41:10 字数 686 浏览 7 评论 0原文

我只是想开发超快速函数来设置和获取 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;
}

I'm just trying to develop ultra-fast functions for setting and getting bits in uint32 arrays. For example, you can say "set bit 1035 to 1". Then, the uint32 indexed with 1035 / 32 is used with the bitposition 1035 % 32. I especially don't like the branching in the setbit function.

Here is my approach:

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;
   }
}

and

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

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

〗斷ホ乔殘χμё〖 2024-10-13 08:41:10

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

其次,您可以使用聪明的位黑客来摆脱分支:

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));
}

First, I would drop the 31u - ... from all expressions: all it does is reordering the bits in your private representation of the bit set, so you can flip this order without anyone noticing.

Second, you can get rid of the branch by using a 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);
}

Third, you can simplify your getter by letting the compiler do the conversion:

bool GetBit(const uint32* data, const uint32 bitpos)
{
    return data[bitpos >> 5u] & (1u << (bitpos & 31u));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文