現在のプロジェクトでは、128ビット値(実際にはmd5ハッシュ)を比較する必要があり、SSE命令を使用して比較を高速化できると思いました。私の問題は、SSE命令に関する適切なドキュメントを見つけることができないことです。あるハッシュが別のハッシュよりも大きいか、小さいか、等しいかを知らせる128ビット整数比較命令を探しています。そのような命令は存在しますか?
PS:対象となるマシンはSSE2命令を備えたx86_64サーバーです。同じ仕事のNEON指導にも興味があります。
現在のプロジェクトでは、128ビット値(実際にはmd5ハッシュ)を比較する必要があり、SSE命令を使用して比較を高速化できると思いました。私の問題は、SSE命令に関する適切なドキュメントを見つけることができないことです。あるハッシュが別のハッシュよりも大きいか、小さいか、等しいかを知らせる128ビット整数比較命令を探しています。そのような命令は存在しますか?
PS:対象となるマシンはSSE2命令を備えたx86_64サーバーです。同じ仕事のNEON指導にも興味があります。
SSEまたはNEON命令セットには128ビット整数比較命令はありません。
SSE4.1は、ベクトル64ビット整数比較(PCMPEQQとPCMPGTQ)を追加しましたが、それらの実装方法のため、これらの2つを128ビット比較にまとめるのは簡単ではありません。
x86_64で128ビットの比較を実行するための推奨される方法は、上位ワードで64ビット比較を使用し、次に上位ワードが等しい場合にのみ下位ワードで追加の64ビット比較を使用することです。
cmp {ahi}, {bhi}
jne 0f
cmp {alo}, {blo}
0: // flags are now set as though a comparison of unsigned 128-bit values
// was performed; signed comparisons are a bit different.
ARMでは、通常のイディオムは、必要に応じてフラグを設定するための単語ごとの条件付き比較のシーケンスです。
実際には、2つの値の128ビット比較であり、2つの命令と前にゼロに設定されたスペアレジスタを備えたSSE4.1を使用して可能ですa
。b
x86アセンブリでは、レガシー128ビットSSEを使用します。
pxor %xmm2, %xmm2 # set xmm2 to zero. Should be moved out of the loop.
# compare %xmm0 to %xmm1 for equality
pxor %xmm0, %xmm1 # xmm1 is zero if both operands are equal
ptest %xmm2, %xmm1 # test not(xmm2) and xmm1. If any bit in xmm1 is set
jc equal # the carry flag is cleared.
not_equal:
...
equal:
Cで組み込み関数を使用することをお勧めします。これは、AVX 3オペランド構文の恩恵を自動的に受け、実際にSSEレジスタの移動を大幅に節約できるためです。
static const __m128i zero = {0};
inline bool compare128(__m128i a, __m128i b) {
__m128i c = _mm_xor_si128(a, b);
return _mm_testc_si128(zero, c);
}
これは上記と同様のコンパイルになります。特に、bool一時が折りたたまれ、キャリーフラグが直接使用されます。
PCMPGTは、128ビット全体を比較するのではなく、常に小さい単位で動作し、個別の結果を生成します。さらに、符号付きの値で機能するため、事態はさらに複雑になります。
64ビットモードで実行している場合は、2つのネイティブ64ビット減算または比較を使用するのが最も速いと思います。
ドキュメントが見つからない理由はわかりません。すべてIntel命令セットリファレンスにあります。