Как работает встроенная функция _mm_cmpgt_epi64

Я использую встроенную функцию _mm_cmpgt_epi64 для реализации 128-битного сложения, а затем 256-битного. Глядя на результат этого внутреннего чего-то, я озадачен.

Я не понимаю, почему вычисленная маска такая, какая она есть.

const __m128i mask = _mm_cmpgt_epi64(bflip, sumflip);

И вот вывод в моем отладчике:

(lldb) p/x bflip
(__m128i) $1 = (0x00000001, 0x80000000, 0x00000000, 0x80000000)
(lldb) p/x sumflip
(__m128i) $2 = (0x00000000, 0x80000000, 0xffffffff, 0x7fffffff)
(lldb) p/x mask
(__m128i) $3 = (0xffffffff, 0xffffffff, 0x00000000, 0x00000000)

Для первой 64-битной полосы (63:0) у меня все в порядке. Но почему вторая полоса (127:64) тоже не заполнена?

Мне кажется, что 0x8000000000000000 > 0x7fffffffffffffff.


person Stringer    schedule 14.10.2018    source источник


Ответы (1)


Похоже, вы печатаете его 32-битными фрагментами, а не 64-битными, так что это странно.

Но в любом случае, это знаковое дополнение до двух целых чисел, как описано в руководстве: http://felixcloutier.com/x86/PCMPGTQ.html

0x8000000000000000 — самое отрицательное 64-битное целое число, а 0x7fffffffffffffff — самое большое положительное.

Если вы хотите сравнение без знака, вам нужно сдвинуть диапазон обоих входов, перевернув их знаковый бит. Логически это вычитание 2^63, чтобы перейти от 0..2^64-1 к -2^63.. 2^63-1. Но мы можем сделать это с более эффективным XOR, потому что XOR — это добавление без переноса, а перенос/заимствование выходит за пределы конца регистра.

const __m128i rangeshift = _mm_set1_epi64x(0x8000000000000000);
const __m128i mask = _mm_cmpgt_epi64(_mm_xor_si128(bflip, rangeshift), _mm_xor_si128(sumflip, rangeshift));

Или используйте AVX512F __mmask8 _mm512_cmp[eq|ge|gt|le|lt|neq]_epu64_mask( __m512i a, __m512i b)

person Peter Cordes    schedule 14.10.2018
comment
Спасибо, да, меня немного смутил тот факт, что я уже выполнил xoring (отсюда и названия bflip и sumflip), и поэтому вычислял gt op в своей голове как беззнаковое сравнение, но, конечно, это было совершенно неправильно. - person Stringer; 15.10.2018
comment
Какой основной процессор поддерживает этот AVX512F? - person Stringer; 15.10.2018
comment
@Stringer: пока нет основных процессоров, только серверные архитектуры Skylake, такие как i9-78xx (высокопроизводительный настольный компьютер) и Skylake Xeon. anandtech.com/show/11550/. И, конечно же, Xeon Phi. Мейнстрим с CannonLake (en.wikipedia.org/wiki/AVX-512#CPUs_with_AVX- 512). Кажется, я читал, что некоторые ноутбуки cannonlake уже могут существовать в дикой природе, но они не являются широко доступными. - person Peter Cordes; 15.10.2018
comment
Так что только Intel, в любом случае я больше планирую купить эти Zen ..., так как у меня уже есть ноутбук Kaby Lake. - person Stringer; 15.10.2018