2016-10-21 2 views
0

Я пытаюсь использовать некоторые инструкции SSE4.2 в алгоритмах соответствия строк, закодированных в C++.Использование инструкции SSE4.2 PCMPESTRM с небольшими шаблонами

Я не понимаю, как использовать эти инструкции, чтобы соответствовать меньшим узорам, и надеялся, что кто-то может помочь мне в этом.

В примере кода я пытаюсь найти шаблон «муравей» внутри упакованной строки «Я антилопа». Я хотел бы надеяться на результат, чтобы быть маска устанавливается на все нули, за исключением для 1 в индексе 8.

Это мой код сейчас, который имеет #include для nmmintrin.h включать инструкции SSE4.2:

void print128_num(__m128i var) 
{ 
    uint8_t *val = (uint8_t*) &var; 
    printf("Text: %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i \n", 
      val[0], val[1], val[2], val[3], val[4], val[5], 
      val[6], val[7], val[8], val[9], val[10], val[11], 
      val[12], val[13], val[14], val[15]); 
} 

int main(){ 

    __m128i s = _mm_set_epi8('e','p','o','l','e','t','n','a',' ','n','a',' ','m','a',' ','i'); 
    __m128i p = _mm_set_epi8(0,0,0,0,0,0,0,0,0,0,0,0,0,'t','n','a'); 

    print128_num(s); 
    print128_num(p); 

    __m128i res = _mm_cmpestrm(s, 16, p, 3, 0); 
    print128_num(res); 

    return 0; 
} 

Я добавил все нули, потому что функция инициализации не даст меньше аргументов. Я понимаю, что это неправильно, но не знал, как это сделать, и сделал несколько довольно отчаянных попыток.

В любом случае это, как я составил: г ++ -g -o sse4test.cpp sse4test -std = C++ 11 -msse4.2

и это мой выход:

Text: 105 32 97 109 32 97 110 32 97 110 116 101 108 111 112 101 
Text: 97 110 116 0 0 0 0 0 0 0 0 0 0 0 0 0 
Text: 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

, который я не понимаю, на самом деле. (последняя строка).

Любая помощь будет очень оценена.

ответ

2

Есть две проблемы с вашим кодом. Во-первых, у вас есть источник и модель обратный в вызове _mm_cmpestrm. Во-вторых, вы указываете 0 для последнего аргумента, который представляет собой набор флагов, определяющих рабочий режим.

Режим нуля выходит как _SIDD_CMP_EQUAL_ANY, описанный как For each character c in A, determine whether any character in B is equal to c.

Для поиска подстроки режим должен быть определен как _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ORDERED | _SIDD_BIT_MASK.

Если вы сделаете эти изменения, вывод будет «0 1», или, другими словами, совпадение 9-го символа.

BTW: Вы можете загрузить из строк с помощью _mm_loadu_si128((__m128i*)(str)); вместо _mm_set_epi8.

Смежные вопросы