web-dev-qa-db-ja.com

ビット演算を使用する利点は何ですか?

最新のCodeProjectニュースレターを読んだ後、私は ビットごとの演算に関するこの記事 に出くわしました。興味深い読み物になり、整数が偶数か奇数かを確認することのメリットは確かにわかりますが、n番目のビットが設定されているかどうかをテストすることはできますか?これの利点は何でしょうか?

19
billy.bob

組み込みシステムでハードウェアレジスタをプログラミングする場合、ビット単位の演算は絶対に不可欠です。たとえば、これまでに使用したすべてのプロセッサには、割り込みを有効にするか無効にするかを制御する1つ以上のレジスタ(通常は特定のメモリアドレス)があります。割り込みで通常のプロセスを起動できるようにするには、その1つの割り込みタイプの有効ビットを設定することですが、最も重要なのは、レジスタ内の他のビットを変更しないことです。

割り込みが発生すると、通常、ステータスレジスタにビットが設定され、単一のサービスルーチンが割り込みの正確な理由を判別できます。個々のビットをテストすることで、割り込みソースの高速デコードが可能になります。

多くの組み込みシステムでは、合計RAM使用可能なバイト数は64、128、または256バイトです(つまり、キロバイトまたはメガバイトではなくバイト)。この環境では、1バイトを使用して複数のデータ項目を保存するのが一般的です。ブールフラグなどを設定し、ビット操作を使用してこれらを設定および読み取ります。

私は何年もの間、メッセージのペイロードが10.5バイトである衛星通信システムを使用してきました。このデータパケットを最大限に活用するには、フィールド間に未使用のビットを残さずに、情報をデータブロックにパックする必要があります。つまり、ビット単位の演算子とシフト演算子を幅広く使用して、情報の値を取得し、送信されるペイロードにパックします。

27
uɐɪ

基本的に、サイズと速度を考慮してこれらを使用します。ビット演算は非常にシンプルなので、通常、算術演算より高速です。たとえば、RGB値の緑の部分を取得するには、算術アプローチは(rgb / 256) % 256。ビット演算では、(rgb >> 8) & 0xFF。後者は大幅に高速で、慣れれば簡単にもなります。一般に、ビット単位の操作は、コンパクトで高速な方法でデータをエンコード/デコードする必要がある場合に多く使用されます。

7
back2dos

これらの種類の操作は、メモリまたはCPUの電力が制限されている組み込みシステム用に書き込むときによく使用されます。

たとえば、スペースを節約するために、各ビットを使用してブール値を表すことにより、単一の8ビットint変数に複数の変数を格納できます。次に、特定のビットを設定したり、ビット値を取得したりするための高速な方法が必要です。

一般に、ギガバイトのメモリを搭載したデスクトップPCでC#のような高水準言語でプログラミングする場合、各boolバイト全体を占める を気にする必要はありません。しかし、2kbのメモリを搭載したCでマイクロコントローラーをプログラミングしている場合、すべてのビットがカウントされるため、8つのブール値を1バイトにパックする機能が重要になる場合があります。

4
Simon P Stevens

ビットワイズ演算は、組み込みエレクトロニクスと同じ理由で、ビデオおよびオーディオコーデックでも頻繁に使用されます。 5つのフラグと11ビットのタイマーをintの半分にパックできることは、非常に効率的なビデオコーデックを作成する場合に非常に便利です。

実際、MPEG 4は可変ビット長フィールドに 指数ゴロムエンコーディング を使用しています。最後のパケットの17または19ビット幅の値は、このパケットのわずか3または5ビット幅である可能性があり、ビット単位の演算ですべてを把握できます。

3
Tacroy

ビットごとの論理演算、ビットごとのシフト演算、および算術演算を組み合わせたトリックは、論理ゲートを使用した(および、またはそうではない)バイナリ加算器の構成を研究した人なら理解できます。そのサークルの外では、詳細なコメントなしに理解することは非常に困難です。

[〜#〜] simd [〜#〜] 単位をプログラミングする場合、特に、CPUのアーキテクチャーがいくつかの他のSIMD命令をエミュレートできるために意図的にいくつかのSIMD命令を省略した場合に役立ちます。

たとえば、アーキテクチャでは、16バイトのグループの負の値を取得するための命令を定義していない場合がありますが、ビット単位の否定と1の加算によってエミュレートできます。同様に、減算は、 2番目のオペランドの負数。 「代替ルート」を利用できることは、特定の指示を省略した理由です。

同様に、SIMDは、16ビット、32ビット、64ビットなどのより広い要素の追加を実装せずに、並列8ビットの追加のみをサポートする場合があります。それらをエミュレートするには、8ビットの計算結果から符号ビットを抽出し、次の要素でキャリー演算を実行する必要があります。

2
rwong

データのパッキング、より高速な演算(2の累乗に合わせると、乗算、除算、係数は大幅に高速になります)、ビットフリッピングなど。それらを学び、それらを使い始めると、ほとんどの利点を自分でゆっくりと始めることができます。

0
user108496