Сравните бит знака в SSE Intrinsics - PullRequest
2 голосов
/ 09 декабря 2011

Как создать маску с использованием встроенных функций SSE, которые указывают, одинаковы ли знаки двух упакованных чисел (__m128), например, при сравнении a и b, где a равно [1,0 -1,0 0,0 2,0], а b равно [1,0 1,0 1.0 1.0] желаемая маска, которую мы получили бы, это [true false true true true].

Ответы [ 2 ]

5 голосов
/ 09 декабря 2011

Вот одно из решений:

const __m128i MASK = _mm_set1_epi32(0xffffffff);

__m128 a = _mm_setr_ps(1,-1,0,2);
__m128 b = _mm_setr_ps(1,1,1,1);

__m128  f = _mm_xor_ps(a,b);
__m128i i = _mm_castps_si128(f);

i = _mm_srai_epi32(i,31);
i = _mm_xor_si128(i,MASK);

f = _mm_castsi128_ps(i);

//  i = (0xffffffff, 0, 0xffffffff, 0xffffffff)
//  f = (0xffffffff, 0, 0xffffffff, 0xffffffff)

В этом фрагменте и i, и f будут иметь одинаковую битовую маску.Я предполагаю, что вы хотите это в типе __m128, поэтому я добавил f = _mm_castsi128_ps(i);, чтобы преобразовать его из __m128i.

Обратите внимание, что этот код чувствителен к знаку нуля.Поэтому 0.0 и -0.0 будут влиять на результаты.


Пояснения:

Код работает следующим образом:

f = _mm_xor_ps(a,b);       //  xor the sign bits (well all the bits actually)

i = _mm_castps_si128(f);   //  Convert it to an integer. There's no instruction here.

i = _mm_srai_epi32(i,31);  //  Arithmetic shift that sign bit into all the bits.

i = _mm_xor_si128(i,MASK); //  Invert all the bits

f = _mm_castsi128_ps(i);   //  Convert back. Again, there's no instruction here.
2 голосов
/ 09 декабря 2011

Посмотрите на инструкцию _mm_movemask_ps, которая выделяет старший значащий бит (т.е. знаковый бит) из 4-х чисел.См. http://msdn.microsoft.com/en-us/library/4490ys29.aspx

Например, если у вас есть [1.0 -1.0 0.0 2.0], то movemask_ps вернет 4 или 0100 в двоичном виде.Итак, если вы получите movemask_ps для каждого вектора и сравните результаты (возможно, поразрядно НЕ XOR), то это будет указывать, все ли знаки одинаковы.

a = [1.0 -1.0 0.0 2.0]
b = [1.0 1.0 1.0 1.0]
movemask_ps a = 4
movemask_ps b = 0
NOT (a XOR b) = 0xB, or binary 1011

Следовательно, знаки одинаковы, за исключением второговекторный элемент.

...