14

リング バッファ サイズが 2 の累乗でなければならないのはなぜですか?

4

1 に答える 1

39

以下に詳述する方法を使用するには、2 の累乗でなければなりません。それ以外である必要はありません。

一般的なアプローチは、"if (index >= size) { index = size - index; }" (サイズ 10、インデックス 10、結果のインデックスは 0) のようになります。これは、次のアプローチに比べて遅く、エラーが発生しやすくなります。

2 の累乗を使用すると、次の利点を活用できます。

size = 32
bin(size) => '00100000'

mask = size - 1;
bin(mask) => '00011111'

このマスクをビット単位の and で適用すると、インデックスが大きくなるにつれて、0 ~ 31 の範囲の数値を構成するビットのみを分離できます。

index = 4
bin(4 & mask) => '00000100' (4)

# index 32 wraps.  note here that we do no bounds checking, 
# no manipulation of the index is necessary.  we can simply 
# and safely use the result.
index = 32
bin(index & mask) => '00000000' (0)

index = 33
bin(index & mask) => '00000001' (1)

index = 64
bin(index & mask) => '00000000' (0)

index = 65
bin(index & mask) => '00000001' (1)

このアプローチは、比較や分岐を必要とせず、安全です (結果のインデックスは常に境界内にあります)。情報を破棄しないという追加の利点があります。インデックス 65 は要素 1 をアドレス指定しますが、インデックスが論理的に 65 であるという情報を保持しています (これは非常に有用です)。

また、これは、インデックスが 3456237 (バッファー内のアドレス 13) に成長した場合と、3 の場合と同じように効率的であることを付け加えたいと思います。

私はパーティーに遅れていることを知っています.どうやってこの質問を見つけたのかさえわかりません:-)これが役に立てば幸いです.

于 2012-07-14T15:21:48.787 に答える