You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:24:50