一、AVX -0影响
在AVX指令运算中,-0和0是不同的,-0运算在常规运算中没有影响,但在按位计算中会造成很严重的影响
比如:
#define AVX_ONE_FLOAT {1.f,1.f,1.f,1.f,1.f,1.f,1.f,1.f}
__m256 one = _mm256_set1_ps(0.f);
__m256 neg_one = _mm256_set1_ps(-0.f);
__m256 one_half = _mm256_set1_ps(-1.f);
__m256 mul = _mm256_and_ps(_mm256_mul_ps(one, one_half),AVX_ONE_FLOAT); // {-1})
__m256 neg_mul = _mm256_and_ps(_mm256_mul_ps(neg_one, one_half),AVX_ONE_FLOAT); //{1}
如上所示,mul和neg_mul的结果完全相反
二、去除-0符号
如何在消除-0的影响时,又能不影响其他值呢,如下所示:
#define EQ_OQ 0x0 //等于 =
#define AVX_ONE_FLOAT {1.f,1.f,1.f,1.f,1.f,1.f,1.f,1.f}
#define AVX_NEG_ONE_FLOAT {-1.f,-1.f,-1.f,-1.f,-1.f,-1.f,-1.f,-1.f}
#define AVX_ZERO_FLOAT {0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f}
#define AVX_NEG_ZERO_FLOAT {-0.f,-0.f,-0.f,-0.f,-0.f,-0.f,-0.f,-0.f}
__m256 value = _mm256_set_ps(0.6f, 0.4f, -0.f, 0, -0.f, -0.6f, -0.3f, -0.1f);
__m256 zero_flg = _mm256_and_ps(_mm256_cmp_ps(value, AVX_NEG_ZERO_FLOAT, EQ_OQ), AVX_NEG_ONE_FLOAT); //取0标志
//{ 0.000000000 0.000000000 0.000000000 -1.00000000 -1.00000000 -1.00000000 0.000000000 0.000000000 }
__m256 dir_flg = _mm256_and_ps(_mm256_or_ps( _mm256_and_ps(value, AVX_NEG_ZERO_FLOAT), AVX_ONE_FLOAT),AVX_NEG_ONE_FLOAT); //取符号
//{ -1.00000000 -1.00000000 -1.00000000 -1.00000000 1.00000000 -1.00000000 1.00000000 1.00000000}
__m256 zero_and_dir = _mm256_and_ps(zero_flg, dir_flg); //-0 方向
//{1.00000000 1.00000000 1.00000000 -1.00000000 1.00000000 -1.00000000 1.00000000 1.00000000 }
__m256 zero_dir = _mm256_or_ps(zero_or_dir, AVX_ONE_FLOAT);
value = _mm256_mul_ps(value, zero_dir); // == 0 {1}
``//{ -0.100000001 -0.300000012 -0.600000024 0.000000000 0.000000000 0.000000000 0.400000006 0.600000024}
1、将-0和0筛选出来
2、取所有值符号
3、取-0和0符号位,移除非0符号影响
4、与-0相乘即可消除-0影响
我蠢了
value = _mm256_add_ps(value, AVX_ZERO_FLOAT); //加0就可以消除影响