2

32 ビット整数の場合、連続する各ビンに 2 倍の整数があるように、連続する整数の 32 個のビンに分割します。最初のビンには 0 が含まれ、2 番目のビンには 0..1 が含まれ、0..2^31-1 まで続きます。

私が思いつく最速のアルゴリズムは、32 ビット整数 i が与えられた場合、i7 で 5 サイクルです (ビット スキャンは 3 サイクルです)。

// bin is the number of leading zeroes, and then we clear the msb to get item
bin_index = bsr(i)
item = i ^ (1 << bin_index)

または同等に (アイテム 0..2^(32-1) をビン 0 に、0 をビン 31 に保存しますが、それは問題ではありません):

// bin is the number of trailing zeroes, and then we shift down by that many bits + 1
bin_index = bsf(i)
item = i >> (bin_index + 1)

いずれの場合も、ビン インデックスは先頭/末尾のゼロ ビットの数としてエンコードされ、アイテム番号からそれらを区切るために 1 が付けられます。先頭または末尾の 1 と、それらを区切るために 0 を使用して同じことを行うことができます。どちらも i=0 では機能しませんが、それは重要ではありません。

整数とビン/アイテムの間のマッピングは、2 倍の連続した整数が連続する各ビンで終了し、ビン内の整数の合計数が 2^32-1 になる限り、完全に任意にすることができます。i7 で 32 個の整数をビンに入れるためのより効率的なアルゴリズムを考えられますか? i7 はスーパースカラーであるため、相互に依存しない操作は、各命令タイプのスループットまで並列に実行できることに注意してください。

4

1 に答える 1

1

ゼロをカウントする前にデータの並べ替えを試みることで、アルゴリズムを改善できます。

たとえば、最初に 2^31 と比較し、大きい場合はそのビンに入れ、そうでない場合は続けて末尾のゼロを数えます。これにより、データセットの半分が 2 つの命令でビンに入れられます...おそらく 2 サイクルです。残りの半分はもう少し時間がかかりますが、最終的な結果は改善されます. 考えれば、この行に従ってさらに最適化できる可能性があります。

これは、分岐予測の効率にも依存すると思います。

于 2013-05-14T03:58:14.850 に答える