如何优化std::array<float,4>的分量越界值检测测试?
4D向量分量范围检测的优化问题
需求说明
我有一个4D向量:std::array<float, 4>,需要检测其所有分量是否处于范围:0.0f <= X && X < 256.0f,只需返回一个bool值判断整个向量是否存在越界分量。
初始实现及汇编输出
代码实现
bool Check_If_Outside_2(std::array<float, 4> vec) { bool outside = false; for (int i = 0; i < 4; i++) if (vec[i] < VType(0) || vec[i] >= VType(256)) outside = true; return outside; }
对应的汇编输出
Check_If_Outside_2(std::array<float, 4ul>): # @Check_If_Outside_2(std::array<float, 4ul>) vxorps xmm2, xmm2, xmm2 vucomiss xmm0, xmm2 setb al vmovss xmm3, dword ptr [rip + .LCPI7_0] # xmm3 = mem[0],zero,zero,zero vucomiss xmm0, xmm3 setae cl or cl, al vmovshdup xmm0, xmm0 # xmm0 = xmm0[1,1,3,3] vucomiss xmm0, xmm2 setb dl vucomiss xmm0, xmm3 setae al or al, dl or al, cl vxorps xmm0, xmm0, xmm0 vcmpltps xmm0, xmm1, xmm0 vpermilps xmm0, xmm0, 212 # xmm0 = xmm0[0,1,1,3] vmovaps xmm2, xmmword ptr [rip + .LCPI7_1] # xmm2 = <2.56E+2,2.56E+2,u,u> vcmpleps xmm1, xmm2, xmm1 vpermilps xmm1, xmm1, 212 # xmm1 = xmm1[0,1,1,3] vorps xmm0, xmm0, xmm1 vpsllq xmm0, xmm0, 63 vmovmskpd ecx, xmm0 or al, cl shr cl or al, cl and al, 1 ret
优化版本及汇编输出
代码实现
利用负整数高位为1的特性,将浮点转换为整数后检测高位是否非零来判断越界:
template<typename T, unsigned long N> static inline std::array<int32_t, N> To_Int_Vec(const std::array<T, N>& x) { std::array<int32_t, N> int_vec; for (int i = 0; i < N; ++i) int_vec[i] = floor(x[i]); return int_vec; } bool Check_If_Outside(std::array<float, 4> vec) { constexpr int32_t neg_mask = ~255; auto vec_int = To_Int_Vec(vec); bool outside = false; for (int i = 0; i < 4; i++) if (vec_int[i] & neg_mask) outside = true; return outside; }
对应的汇编输出
Check_If_Outside(std::array<float, 4ul>): # @Check_If_Outside(std::array<float, 4ul>) vshufps xmm0, xmm0, xmm1, 65 # xmm0 = xmm0[1,0],xmm1[0,1] vroundps xmm0, xmm0, 9 vcvttps2dq xmm0, xmm0 vpshufd xmm1, xmm0, 78 # xmm1 = xmm0[2,3,0,1] vpor xmm0, xmm0, xmm1 vpshufd xmm1, xmm0, 229 # xmm1 = xmm0[1,1,2,3] vpor xmm0, xmm0, xmm1 vmovd eax, xmm0 cmp eax, 255 seta al ret
疑问
我认为可借助Intel SIMD指令进一步优化,但不确定实现方式:能否用纯C++优化?还是需要intrinsics或内联汇编?是否存在进一步优化的空间?
编译环境:x86-64 clang 11.0.0,编译选项:-O3 -mtune=skylake -ffast-math -funsafe-math-optimizations -fno-math-errno -msse4.1 -mavx -mfma4
编辑:问题已在帮助下解决!谢谢!
内容的提问来源于stack exchange,提问作者user19179144
相关产品推荐
相关产品推荐

