2014-12-15 4 views
4

В основном проблема связана с ассемблером x86, где у вас есть номер, который вы хотите установить либо на нуль, либо на номер с номером, используя and. Если вы , то номер с отрицательным вы получите номер сам, но если вы and с нулем, вы получите нуль.SSE intrinsics: маскирование поплавка и использование побитового и?

Теперь проблема, с которой я столкнулась в SSE, заключается в том, что поплавки не совпадают в двоичном формате, как в двойных (или, может быть, я ошибаюсь). В любом случае, вот код, я пробовал использовать все виды поплавков для маскировки второго и третьего номеров (127.0f и 99.0f соответственно), но не повезло.

#include <xmmintrin.h> 
#include <stdio.h> 

void print_4_bit_num(const char * label, __m128 var) 
{ 
    float *val = (float *) &var; 
    printf("%s: %f %f %f %f\n", 
     label, val[3], val[2], val[1], val[0]); 
} 
int main() 
{ 
    __m128 v1 = _mm_set_ps(1.0f, 127.0f, 99.0f, 1.0f); 
    __m128 v2 = _mm_set_ps(1.0f, 65535.0f, 127.0f, 0.0f); 
    __m128 v = _mm_and_ps(v1, v2); 

    print_4_bit_num("v1", v1); 
    print_4_bit_num("v2", v2); 
    print_4_bit_num("v ", v); 

    return 0; 
} 

ответ

4

При использовании AND вам необходимо использовать поразрядную (целую) маску, т.е. четкие альтернативные значения в векторе вы могли бы сделать что-то вроде этого:

__m128 v1 = _mm_set_ps(1.0f, 127.0f, 99.0f, 1.0f); 
__m128 v2 = _mm_castsi128_ps(_mm_set_epi32(0, -1, 0, -1)); 
__m128 v = _mm_and_ps(v1, v2); // => v = { 0.0f, 127.0f, 0.0f, 1.0f } 
+0

Каковы заголовки '_mm_castsi128_ps' и' _mm_set_epi32'? Спасибо. – pandoragami

+0

Это просто базовый материал SSE2, поэтому '#include" emmintrin.h "'. См. Очень полезное [Intel Intrinsics Guide] (https://software.intel.com/sites/landingpage/IntrinsicsGuide/) для дальнейшего использования. –

+1

Большое спасибо! – pandoragami

2

Вы можете бросить любой вектор SSE для любого векторного типа SSE одного и того же размера (128 бит или 256 бит), и вы получите те же самые биты, как и раньше; фактического кода не будет. Очевидно, что если вы отбрасываете 4 поплавка на 2 двойных, вы получаете вздор, но для вашего случая вы бросаете float на какой-то целочисленный тип, делайте и, отдавайте результат назад.

0

Если у вас есть SSE4.1 (который я держал пари, вы делаете), вы должны рассмотреть _mm_blendv_ps(a,b,mask). Это использует только знак знака своего аргумента mask и, по существу, реализует векторизованный mask<0?b:a.

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