1

ビット シフトとマスキングを組み合わせてアプローチする 2 つの異なる方法を見てきましたが、結果がブール値として使用されると仮定して同等であるか、または一方が他方よりも問題が少ないか、パフォーマンスが優れているかどうか疑問に思っていました。

二つ:

flags & (BIT_MASK << BIT_NUMBER)

また

(flags >> BIT_NUMBER) & BIT_MASK

前者は、 のサイズに応じて一部のプラットフォームで問題が発生する可能性があるようですflags。つまり、ビット シフトによってマスクが一時変数の先頭に押し出される可能性があります。これは問題ですか?アップシフトとダウンシフトでパフォーマンスの違いはありますか?

BIT_MASKとを組み合わせBIT_NUMBERて 1 つの明確なマスクにすることで、さらに良い結果が得られますが、変更を最小限に抑えたいレガシ コードを使用しています。

4

3 に答える 3

2

flags & (BIT_MASK << BIT_NUMBER)1ビットアンド命令で実行できます。

(flags >> BIT_NUMBER) & BIT_MASKシフトとそれに続くビットアンドの 2 つの命令が必要です。

(実際、PowerPC では、2 番目のバージョンにも専用のオペコードがありrlwinmますが、Intel にはそのような運がありません。)

もちろん、最大の違いは、異なる結果値を生成することです。ゼロまたは非ゼロのみをチェックしている場合は、単一の命令であるため、最初のバージョンをお勧めします。

于 2013-02-05T22:05:26.360 に答える
1

BIT_MASKとが定数の場合BIT_NUMBER、コンパイラはおそらく式を事前に計算し、それらをグループ化すると命令を保存します。これは、最初のアプローチを支持します。

複数のビットを取得しようとしている場合は、結果を右にシフトする必要があります。これは、2 番目のアプローチを支持します。

于 2013-02-05T22:01:21.447 に答える
0

コンパイラのバックエンドが何をするかという観点から考えないことをお勧めします。最適化を使用していない場合は問題ではなく、最適化を使用している場合は、優れたコンパイラはわずかな命令で正しいことを行います。コンパイルターゲットに対して可能な限り。

それが言語で意味的に何を意味するかという観点から考えてください。たとえば、flags の型uint64_tBIT_NUMBER31 より大きい場合、2 番目の形式のみが意図したとおりに動作する可能性があります。その理由は、おそらく 32 ビットである(BIT_MASK << BIT_NUMBER)として評価され、ゼロに評価される 31 よりも大きいため、AND の後に全体がゼロになるためです。一方、64 ビット式として評価され (フラグは 64 ビットであるため)、AND を実行する前に適切にシフトされます。intBIT_NUMBER(flags >> BIT_NUMBER)

Clang コンパイラに関する興味深い話については、Clang: Defending C++ from Murphy's Million Monkeysを参照してください。これは、今日のコンパイラで可能なセマンティック理解の深さを示しています21:25。 . これはトークで使用された例です

static const long long DiskCacheSize = 8 << 30; // 8 Gigs

Clang gives:

% clang++ -std=c++11 -fsyntax-only overflow.cpp
overflow.cpp:1:42: warning: signed shift result (0x200000000) requires 35 
bits to represent, but 'int' only has 32 bits [-Wshift-overflow]
static const long long DiskCacheSize = 8 << 30; // 8 Gigs
                                       ~ ^  ~~

最近、gcc および Java JIT コンパイラーが、たとえば、シフト、マスク、および OR のグループが本質的に 32 ビット量の回転を行っていることを理解できるほど賢く、回転命令を生成することを知って驚きました。ビット単位のローテーションは、現在の Intel CPU のシフトよりも遅いですか? . 最近のコンパイラは非常に優れています。

于 2013-02-05T22:10:23.923 に答える