4

OK、私が欲しいのはかなり簡単です:

  • 数値の N 番目のビットを設定する (= '1' にする)
  • 数値の N 番目のビットを設定解除する (= '0' にする)

これはこれまでの私のコードです(2つのマクロの形式で):

#define SETBIT(X,Y)     X|=(1ULL<<(Y))
#define UNSETBIT(X,Y)   X&=(~(1ULL<<(Y)))

どちらも正常に動作しています。ことは次のとおりです。

  • 最適化できるものはありますか?
  • もっと速くすることはできますか?

(どちらの操作も毎秒数百万回実行されることになっているため、パフォーマンスは非常に重要です)。

4

4 に答える 4

6

マクロを取り除くことでコンパイル時間をわずかに短縮できますが、それだけです。ビットいじりは十分に速いので、問題にはなりません。

これは慣用的な方法です。私は何も変えません。

于 2012-12-30T16:04:54.267 に答える
3

これは、C でビットを設定およびクリアする標準的な方法です。

これらのマクロを高速化する可能性がある場合は、これらの操作の Linux アセンブリ実装を確認できます。

たとえば、次の場合x86:

http://lxr.linux.no/linux/arch/x86/include/asm/bitops.h

関数を探して__clear_bitインライン__set_bit化します。

于 2012-12-30T16:11:17.223 に答える
2

これらのマクロは最適慣用的であるため、最適化を行う必要がある場合、コンパイラはおそらくこれらの式を認識します。

あなたが得られる唯一のスピードアップは...より良い代替手段がある場合はそれらの使用を避けることです. 同じマルチビット操作 (たとえば、ビット 0、2、および 4 をオンにする) を頻繁に行う場合は、複数の を使用する代わりに、たとえば単一のorSETBITを使用してこれらすべての操作を実行することで、何かを得ることができます。

于 2012-12-30T16:08:21.657 に答える
2

まず、マクロを次のように修正する必要があります。

#define SETBIT(X,Y)     ( (X) |= 1ULL << (Y) )
#define UNSETBIT(X,Y)   ( (X) &= ~(1ULL << (Y)) ) )

そうすれば、次のようなコードSETBIT(a, 2) + 1;が期待どおりに機能し、SETBIT(1+a, 2);期待どおりにエラーが発生します。

()おそらくそのようにマクロを使用することはありませんが、余分な括弧はとにかく無料であり、マクロ関連の問題を解決することは、常に余分なマクロやマクロを配置するような PITA になる可能性があり{}ます。

追加: インライン アセンブリとビット ローテーション操作を使用する CPU を使用し、コンパイル時に不明であると仮定Yすると、UNSETBIT を高速化して、NOT を回避できます... 疑似コード:

X = X OR (0xFFFFFFFFFFFFFFFE ROL Y)

次に、これらのマクロは可能な限り効率的ですが (C コンパイラはそれらを理想的なアセンブリ命令に最適化する必要があります)、次のようないくつかのビットを操作するマクロを提供する必要があります。

#define SET2BITS(X, B1, B2)     ( (X) |= 1ULL << (B1) | 1ULL << (B2) )

また、式の中で使用するための関数のようなマクロは、状況によってはより効率的かもしれません (ただし、コンパイラの最適化はおそらく同じ最終結果を達成します):

#define BITSETVAL(X, B)     ( (X) | 1ULL << (B) )
于 2012-12-30T16:56:44.960 に答える