0

私は以下のコードを見つけました:

http://msdn.microsoft.com/en-us/library/bb513993(v=vs.90).aspx

私はコードが何をしているのかを正確に理解しようとしています。文字列内のスペース文字を非常に高速に見つけるために組み込み関数を使用することに興味があり、これらの文字列組み込み関数が役立つと思います。

printfステートメントで提供される「コメント」がよくわかりません。なぜ期待される結果が著者が述べたものなのですか?

(以下をコピーして貼り付けて、すぐに実行できるはずです)

#include <stdio.h>
#include <nmmintrin.h>
#include <iostream>

using namespace std;

int main ()
{
    __m128i a, b;


    const int mode = _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_EACH | _SIDD_LEAST_SIGNIFICANT;
    //      _SIDD_UWORD_OPS         a and b contain strings of unsigned 16-bit characters.  
    //      _SIDD_CMP_EQUAL_EACH    Find if equal each mode: This implements the string equality algorithm.
    //      _SIDD_LEAST_SIGNIFICANT sets the same bit as _SIDD_BIT_MASK


    a.m128i_u16[7] = 0xFFFF;
    a.m128i_u16[6] = 0xFFFF;
    a.m128i_u16[5] = 0xFFFF;
    a.m128i_u16[4] = 0xFFFF;
    a.m128i_u16[3] = 0xFFFF;
    a.m128i_u16[2] = 0xFFFF;
    a.m128i_u16[1] = 0xFFFF;
    a.m128i_u16[0] = 0xFFFF;

    b.m128i_u16[7] = 0x0001;
    b.m128i_u16[6] = 0x0001;
    b.m128i_u16[5] = 0x0001;
    b.m128i_u16[4] = 0x0001;
    b.m128i_u16[3] = 0x0001;
    b.m128i_u16[2] = 0x0001;
    b.m128i_u16[1] = 0x0001;
    b.m128i_u16[0] = 0x0001;

    int returnValue = _mm_cmpistra(a, b, mode);
    printf_s("_mm_cmpistra return value should be 1: %i\n", returnValue);

    b.m128i_u16[4] = 0x0000;
    returnValue = _mm_cmpistra(a, b, mode);
    printf_s("_mm_cmpistra return value should be 0: %i\n", returnValue);

    b.m128i_u16[5] = 0xFFFF;
    returnValue = _mm_cmpistrc(a, b, mode);
    printf_s("_mm_cmpistrc return value should be 0: %i\n", returnValue);

    b.m128i_u16[4] = 0x0001;
    returnValue = _mm_cmpistrc(a, b, mode);
    printf_s("_mm_cmpistrc return value should be 1: %i\n", returnValue);

    returnValue = _mm_cmpistri(a, b, mode);
    printf_s("_mm_cmpistri return value should be 5: %i\n", returnValue);

    b.m128i_u16[0] = 0xFFFF;
    __m128i fullResult = _mm_cmpistrm(a, b, mode);
    printf_s("_mm_cmpistrm return value: 0x%016I64x 0x%016I64x\n",
                fullResult.m128i_u64[1], fullResult.m128i_u64[0]);

    returnValue = _mm_cmpistro(a, b, mode);
    printf_s("_mm_cmpistro return value should be 1: %i\n", returnValue);

    returnValue = _mm_cmpistrs(a, b, mode);
    printf_s("_mm_cmpistrs return value should be 0: %i\n", returnValue);

    a.m128i_u16[7] = 0x0000;
    returnValue = _mm_cmpistrs(a, b, mode);
    printf_s("_mm_cmpistrs return value should be 1: %i\n", returnValue);

    returnValue = _mm_cmpistrz(a, b, mode);
    printf_s("_mm_cmpistrz return value should be 0: %i\n", returnValue);

    b.m128i_u16[7] = 0x0000;
    returnValue = _mm_cmpistrz(a, b, mode);
    printf_s("_mm_cmpistrz return value should be 1: %i\n", returnValue);

    int bb;
    cin >> bb;

    return 0;
}
4

1 に答える 1

3

あなたは今までに気が狂ったか、それを理解しました。しかし...「i」で終わる組み込み関数は、何らかの出現のインデックスを返します。'm' で終わる組み込み関数はマスクを返します (ビット/バイト/ワードは ... に応じて) 'c'、'o'、's'、または 'z' で終わる組み込み関数は、単一の EFLAGS ビットを返します。「a」で終わる組み込み関数は、CFlag と ZFlag のブール値の結果を返します。(AFlag ではありません。) これは、探しているイベントの発生と入力の 1 つの終了の両方を 1 つの命令で簡単にテストできるようにするために行われました。これらの命令を高水準言語でどのように使用するかを考えるのは、本当にひどい仕事でした。当時、私はこれらの命令にアクセスするためにインライン ASM にドロップすることに完全に満足していました。彼らは本当に少し... 複雑です... Cのような高級言語で効率的に使用するためです。申し訳ありません。もしあなたが ASM に立ち寄れば、とても楽しいものになるでしょう。3つまたは4つの命令ループでどれだけの作業を実行できるかは、ちょっとクールです。

于 2014-04-10T04:53:47.783 に答える