Intel 64 で実行する論理検証問題をベクトル化しようとしています。
私は最初に問題を説明しようとします:
v[]
コンパイル時にすべて既知の 70 ビット整数 (約 400,000 個) の静的配列があります。
プロデューサは 70 ビット整数a
を大量に非常に迅速に作成します。
それぞれについて、 whicha
の要素が存在するかどうかを調べる必要があります。v
v[i] & a == 0
これまでのところ、C での私の実装は次のようなものです (簡略化):
for (; *v; v++) {
if (!(a & *v))
return FOUND;
}
// a had no matching element in v
return NOT_FOUND;
SSE/AVX を使用してこれを最適化し、プロセスを高速化し、これらのテストを並行して実行することを検討しています。それぞれをレジスターにロードa
し*v
て、検証を行うためXMM
の命令を呼び出すところまで行きました。PTEST
YMM
これを拡張して、新しいレジスタの 256 ビットすべてを使用する方法があるかどうか疑問に思っています。3x70 ビットを 1 つのレジスタに詰め込むことはできますか? テストごとに1つのレジスタを使用するだけでなく、正当化するのに十分な効率でそれらをパック/アンパックする方法はよくわかりません。
入力の性質についてわかっていることがいくつかあります。
- のすべての要素には、
v[]
設定されているビット数が非常に少ない v[]
70ビット未満を使用するように並べ替え/圧縮することはできません- 平均で約20%確認後、
FOUND
条件が満たされる見込みです。v[]
a
バッチでチェックする前に、複数をバッファすることができます。v[]
のどの要素が一致したかを必ずしも知る必要はありません。一致したかどうかだけを知る必要があります。- プロデュース
a
に必要なメモリは非常に少ないため、前回の呼び出しで L1 に残っていたものはまだ残っている可能性があります。
結果のコードは、SSE4.2、AVX 命令をサポートする最新世代の Intel Xeon プロセッサで実行することを目的としています。Intel C コンパイラまたは少なくとも GCC でコンパイルされるアセンブリまたは C を喜んで受け入れます。