7


現在のプロジェクトでは、128ビット値(実際にはmd5ハッシュ)を比較する必要があり、SSE命令を使用して比較を高速化できると思いました。私の問題は、SSE命令に関する適切なドキュメントを見つけることができないことです。あるハッシュが別のハッシュよりも大きいか、小さいか、等しいかを知らせる128ビット整数比較命令を探しています。そのような命令は存在しますか?

PS:対象となるマシンはSSE2命令を備えたx86_64サーバーです。同じ仕事のNEON指導にも興味があります。

4

3 に答える 3

7

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では、通常のイディオムは、必要に応じてフラグを設定するための単語ごとの条件付き比較のシーケンスです。

于 2010-12-26T16:41:52.550 に答える
7

実際には、2つの値の128ビット比較であり、2つの命令と前にゼロに設定されたスペアレジスタを備えたSSE4.1を使用して可能ですab

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一時が折りたたまれ、キャリーフラグが直接使用されます。

于 2012-03-21T15:25:01.023 に答える
2

PCMPGTは、128ビット全体を比較するのではなく、常に小さい単位で動作し、個別の結果を生成します。さらに、符号付きの値で機能するため、事態はさらに複雑になります。

64ビットモードで実行している場合は、2つのネイティブ64ビット減算または比較を使用するのが最も速いと思います。

ドキュメントが見つからない理由はわかりません。すべてIntel命令セットリファレンスにあります。

于 2010-12-26T15:55:10.587 に答える