これはおそらく言語に依存しませんが、私は C++ のバックグラウンドから質問しています。
組み込みシステム (AVR、8 ビット) 用のリング バッファを一緒にハッキングしています。仮定しましょう:
const uint8_t size = /* something > 0 */;
uint8_t buffer[size];
uint8_t write_pointer;
次のように、バッファが 2 のべき乗である場合に、効率的なブランチレス ロールオーバーを行うために&
、書き込みポインタと読み取りポインタを ing する巧妙なトリックがあります。size-1
size
// value = buffer[write_pointer];
write_pointer = (write_pointer+1) & (size-1);
ただし、サイズが 2 の累乗でない場合、フォールバックはおそらくポインター (つまりインデックス) とサイズの比較であり、条件付きリセットを行います。
// value = buffer[write_pointer];
if (++write_pointer == size) write_pointer ^= write_pointer;
リセットはめったに発生しないため、これはあらゆる分岐予測にとって簡単なはずです。
ただし、これは、ポインターがメモリ内で前方に進む必要があることを前提としています。size
これは直感的ですが、反復ごとにの負荷が必要です。通常のケースでは、順序を逆にする (後方に進む) と、より良い CPU 命令 (すなわち ) が生成されると思います。これは、リセット中にのみ必要になるためです。jump if not zero
size
// value = buffer[--write_pointer];
if (write_pointer == 0) write_pointer = size;
それで
TL;DR: 私の質問は次のとおりです:メモリを後方に移動すると、キャッシュ ミスが原因で実行時間に悪影響がありますか (メモリを単純に前方に読み取ることができないため)、またはこれは有効な最適化ですか?