3

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

ありがとうございました!

4

1 に答える 1

0

まず、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);
}

第三に、コンパイラに変換を行わせることで、ゲッターを単純化できます。

bool GetBit(const uint32* data, const uint32 bitpos)
{
    return data[bitpos >> 5u] & (1u << (bitpos & 31u));
}
于 2012-02-07T21:45:49.550 に答える