ブランチなしで自動的にオーバーフローを処理するセーフバッファのタイプを作成しようとしています。バッファサイズは2の累乗であり、有効な正の(すなわち、ゼロを含まない)インデックスのみを有するものとする。また、インデックスに格納された要素が検索キーと等しい場合は、指定されたインデックスでの削除である、チェックされた削除も可能です。ブランチレスオーバーフローの処理
私は基本的にこの
Element *buffer[256];
inline void buffer_insert(size_t index, Element *elem){
buffer[index < 256 && index] = elem;
}
//Optional: checked insert to prevent overwrite. Will only insert
//if the buffer holds NULL at index.
inline void buffer_checkedInsert(size_t index, Element * elem){
buffer[index && !buffer[index < 256 && index]] = elem;
}
inline void buffer_checkedRemove(size_t index, Element *elem){
buffer[0] = NULL; //Maybe useful if buffer[0] stores elem
buffer[((elem == buffer[index < 256 && index)) && index] = NULL;
}
buffer[0]
が有効なバッファ・インデックスではありませんように、私は基本的に、渡されたインデックスが範囲外であるときはいつでも、インデックス0にアクセスするような何かのために行っていました。また、削除される要素が削除に渡される要素と等しくないときはいつでもインデックス0にアクセスする必要があります。また、バッファにインデックスに何かが含まれている場合は、インデックス0にアクセスすることもできます。
私の質問は以下のとおりです。
- は、私は本当に無店舗を持っているものですか? Cコンパイラが& &の短絡を使用することを決定した場合、コードが分岐する可能性があるためです。
- & &が分岐を引き起こす場合、分岐を伴わない同じ振る舞いを持つ代替案がありますか?
- これは基本的なオーバーフローチェックよりも高速ですか?あるいは、Cコンパイラがどうにかして
if(index < 256) buffer[index] = elem
のブランチレス版を与えることができましたか?
'&&'は意図的に短絡しています。その使用は一般的に支店を出す。比較演算子の結果を値として使用すると、アーキテクチャーに応じてブランチが生成されることもあります(x86ではそうではありません)。 – fuz
概念的な質問として、境界外の読み書きを静かに行うのが本当に良いのかどうかは、静かにするのではなく、何もしないでください。また、ブランチレスコードが本当に追加の長さに見合う価値があるかどうかも考えてください。ジャンプがほとんど決してとられていないのは、非常に安価で、私は時々よりもオーバーフローチェックをトリガーするつもりはないと思います。 – fuz
'&&'はあなたが思っていることをしません。例えば'&&'の結果は '0'または' 1'のみになります。 – Hurkyl