128-битное сравнение хешей с SSE - PullRequest
6 голосов
/ 26 декабря 2010


В моем текущем проекте мне нужно сравнить 128-битные значения (на самом деле хэши md5), и я подумал, что можно было бы ускорить сравнение, используя инструкции SSE. Моя проблема в том, что мне не удается найти хорошую документацию по инструкциям SSE; Я ищу 128-битную инструкцию сравнения целых чисел, которая дает мне знать, если один хеш больше, меньше или равен другому. Существует ли такая инструкция?

PS: целевыми машинами являются серверы x86_64 с инструкциями SSE2; Меня также интересует инструкция NEON для той же работы.

Ответы [ 3 ]

7 голосов
/ 26 декабря 2010

В наборах команд SSE или NEON нет 128-битных инструкций сравнения целых чисел.

SSE4.1 добавил 64-битные сравнения целочисленных векторов: PCMPEQQ и PCMPGTQ, но из-за способа их реализацииНепросто соединить два из них в 128-битное сравнение.

Предпочтительный способ выполнить 128-битное сравнение на x86_64 - это использовать 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 обычная идиома - это последовательность условных сравнений слово за словом для установки флагов по мере необходимости.

6 голосов
/ 21 марта 2012

На самом деле 128-битное сравнение двух значений a и b возможно при использовании SSE 4.1 с двумя инструкциями и резервным регистром, установленным в ноль ранее.

В сборке 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 сворачивается и флаг переноса используется напрямую.

2 голосов
/ 26 декабря 2010

PCMPGT не будет сравнивать все 128 бит, он всегда будет работать с меньшими единицами и давать отдельные результаты. Кроме того, он работает со знаковыми значениями, что еще более усложняет ситуацию.

Если вы работаете в 64-битном режиме, я думаю, что будет быстрее всего использовать два собственных 64-битных вычитания или сравнения.

Не уверен, почему вы не можете найти документацию, это все в справочнике по набору инструкций Intel .

...