最好的方法来计算最大掩码的sse var
Best way to compute max mask of sse var
(我只对前3个组件感兴趣)
例如: [ 1 2 3 ? ]
应该产生[ 0 0 -1 ? ]
同样,重要的是只设置一个"位",以便:[ 1 2 2 ? ]
不应生成[ 0 -1 -1 ? ]
而是[ 0 -1 0 ? ]
或[ 0 0 -1 ? ]
(无论哪个)
后一种(坏的)解决方案是可能的,例如通过提取水平最大值并与原始值进行比较:
__m128 abcd; // input
__m128 ccac = _mm_shuffle_ps(abcd, abcd, 0x8A);
__m128 abcd_ccac = _mm_max_ps(abcd, ccac);
__m128 babb = _mm_shuffle_ps(abcd, abcd, 0x51);
__m128 abcd_ccac_babb = _mm_max_ps(abcd_ccac, babb);
__m128 mask = _mm_cmpeq_ps(abcd, abcd_ccac_babb);
也许一些按位操作来消除重复的集合位?
更新:
我又想出了一个(糟糕的)解决办法。关键是将每个组件与另一个组件进行比较,避免等式(不将
a >= b
和b >= a
放在另一个地方)。
a > b & a >= c
b > c & b >= a
c > a & c >= b
产量:
([ a b c ? ] > [ b c a ? ]) & ([ a b c ? ] >= [ c a b ? ])
和代码中的
__m128 abcd; // input
__m128 bcad = _mm_shuffle_ps(abcd, abcd, 0xC9);
__m128 gt = _mm_cmpgt_ps(abcd, bcad);
__m128 cabd = _mm_shuffle_ps(abcd, abcd, 0xD2);
__m128 ge = _mm_cmpge_ps(abcd, cabd);
__m128 mask = _mm_and_ps(gt, ge);
在[ x x x ? ]
的情况下失败(生成[ 0 0 0 ? ]
)。
接近:-)
任何想法?
更新:
我现在使用以下解决方案:
__m128 abcd; // input
__m128 bcad = _mm_shuffle_ps(abcd, abcd, 0xC9);
__m128 gt = _mm_cmpgt_ps(abcd, bcad);
__m128 cabd = _mm_shuffle_ps(abcd, abcd, 0xD2);
__m128 ge = _mm_cmpge_ps(abcd, cabd);
__m128 and = _mm_and_ps(gt, ge);
__m128i bits = _mm_setr_epi32(_mm_movemask_ps(and), -1, -1, -1);
__m128i dirt = _mm_cmpeq_epi32(bits, _mm_setzero_si128());
__m128i mask = _mm_or_si128(dirt, _mm_castps_si128(and));
我还没有测试过这个,但我相信它只会在最大值的第一次(最高阶)出现时得到-1:
__m128 abcd; // input
__m128 ccac = _mm_shuffle_ps( abcd,abcd,0x8A );
__m128 abcd_ccac = _mm_max_ps( abcd,ccac );
__m128 babb = _mm_shuffle_ps( abcd,abcd,0x51 );
__m128 abcd_ccac_babb = _mm_max_ps( abcd_ccac,babb );
__m128 mask = _mm_cmpeq_ps( abcd,abcd_ccac_babb );
// set the '?' position in mask to zero
mask = _mm_blend_ps( mask,_mm_setzero_ps(),0x08 );
// shift mask left 32 bits shifting in zeros
__m128 maskSrl32 = _mm_shuffle_ps( mask,mask,_MM_SHUFFLE( 3,1,0,3 ) );
// shift mask left 64 bits shifting in zeros
__m128 maskSrl64 = _mm_shuffle_ps( mask,mask,_MM_SHUFFLE( 3,0,3,3 ) );
// andnot the shifted masks with mask
// in doing so, the higher order set bits will suppress any set bits which follow
mask = _mm_andnot_ps( maskSrl32,mask );
mask = _mm_andnot_ps( maskSrl64,mask );
// select -1 using the final mask
__m128 result = _mm_and_ps( mask,_mm_set1_ps( -1.0f ) );
倒转移位方向,在最低阶最大位置产生-1
相关文章:
- 位移操作和位掩码未检测到重复字符
- OpenCV - 带有掩码的absdiff
- 生成前缀位掩码
- 如何从__m64值的 lsb 创建 8 位掩码?
- 如何对无符号长 int 进行位掩码?
- 删除K的背景掩码-意味着Python或C++中的集群/
- 如何在C++中优雅地处理位掩码
- 将uint64_t位掩码转换为 std::布尔数组
- 使输入二进制掩码适应 ITK 网格生成器
- 如何从 getifaddr 读取子网掩码
- 优化从子位掩码生成父位掩码
- 基于模式创建位掩码作为 constexpr
- 使用二进制掩码 C++ ITK 获取感兴趣区域
- C++中的运行时位复制(位掩码)
- 根据 IP 和掩码C++打印所有 IP
- C++设置"blank"或重置 ifstrean (ios) 的异常掩码
- OpenCV 检测带有掩码的斑点
- OPENCV:如何创建多边形形状的掩码
- 递归函数,用于使用位掩码 c++ 显示集合的所有子集
- 最好的方法来计算最大掩码的sse var