SSE指令集:如何对浮点数进行掩码操作并使用按位与运算?

4
基本上这个问题与x86汇编有关,其中有一个数字,你想将它设置为零或数字本身,使用and。如果你用负一and这个数字,你会得到数字本身,但如果你用零and它,你就得到了零。
现在我在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;
}
3个回答

5

当你使用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 }

_mm_castsi128_ps_mm_set_epi32的头文件是什么?非常感谢。 - pandoragami
这只是基本的SSE2内容,所以要#include "emmintrin.h"。将来可以参考非常有用的Intel Intrinsics Guide - Paul R

3
你可以将任何SSE向量转换为相同大小的任何SSE向量类型(128位或256位),你将获得与以前完全相同的位;不会有任何实际代码。显然,如果你将4个浮点数转换为2个双精度浮点数,那么你会得到无意义的结果,但对于你的情况,你可以将浮点数转换为某个整数类型,执行AND运算,再将结果转换回来。

0

如果您拥有SSE4.1(我敢打赌您肯定有),那么您应该考虑使用_mm_blendv_ps(a,b,mask)。它仅使用其mask参数的符号位,并实现了矢量化的mask<0?b:a


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接