よく知られているMITビットカウントアルゴリズムのバージョンを使用して、SSE2命令を使用してコンウェイのライフゲームで隣人をカウントしたいと思います。
これがcのMITビットカウントで、63ビットを超えるビットカウントをカウントするように拡張されています。
int bitCount(unsigned long long n)
{
unsigned long long uCount;
uCount = n – ((n >> 1) & 0×7777777777777777)
- ((n >> 2) & 0×3333333333333333)
- ((n >> 3) & 0×1111111111111111);
return ((uCount + (uCount >> 4))
& 0x0F0F0F0F0F0F0F0F) % 255;
}
これがPascalのバージョンです
function bitcount(n: uint64): cardinal;
var ucount: uint64;
begin
ucount:= n - ((n shr 1) and $7777777777777777)
- ((n shr 2) and $3333333333333333)
- ((n shr 3) and $1111111111111111);
Result:= ((ucount + (count shr 4))
and $0F0F0F0F0F0F0F0F) mod 255;
end;
この構造のビットを並行してカウントしようとしています。
32-bit word where the pixels are laid out as follows.
lo-byte lo-byte neighbor
0 4 8 C 048C 0 4 8 C
+---------------+
1|5 9 D 159D 1|5 9 D
| |
2|6 A E 26AE 2|6 A E
+---------------+
3 7 B F 37BF 3 7 B F
|-------------| << slice A
|---------------| << slice B
|---------------| << slice C
この構造の中央に16ビットがあり、検索する必要があることに注意してください。SSE2を使用して、中央の16ビットのそれぞれのネイバーカウントを計算したいと思います。これを行うために、スライスAをXMM0ローワードワードに、スライスBをXXM0-dword1などに配置します。XMM0をXMM1にコピーし、XMM0のローワードのビットのビット
をマスクします。XMM0のワード1についても同じようにします。異なるスライスとマスクを使用して、XMM0とXMM1の各単語が異なるピクセルのネイバーを保持していることを確認します。012-456-89A
5
質問
MITビットカウントを微調整して、各XMMワードのワード/ピクセルあたりのビットカウントを取得するにはどうすればよいですか。
備考
ルックアップテーブルを使用したくないのは、すでにそのアプローチがあり、SSE2がルックアップテーブルへのメモリアクセスを必要としないことでプロセスを高速化するかどうかをテストしたいからです。
私はこれをDelphiでプログラミングしており、x86 + SSE2アセンブリコードを使用しているため、SSEアセンブリを使用した回答が最適です。