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

无分支优化:判断无符号整数是否属于两个编译时常量区间

无符号整数双区间归属检查的无分支优化方案需求

在大量场景中,我需要判断给定无符号整数是否属于两个不重叠区间之一,但这类检查往往存在明显性能损耗。我的实现优先级从高到低为:

  1. 消除数据相关分支
  2. 最小化总操作数
  3. 缩短依赖链(因关注吞吐量,该优先级最低)

多数场景下无符号整数为32位(例如用整数运算模拟float操作),为便于研究与阐述,我选用C++的uint8_t类型展开分析,以此规避RISC处理器上整数常量高效构造等额外问题。

通过对比编译输出与手动优化示例,发现现代编译器通常能为可通过AND处理的场景生成最优代码(如下方代码示例的case 2、3),但无法处理依赖XOR将两个区间转换为一个区间的场景(如case 0、1)。也可基于OR构建优化方案(如case 4),但这类方案总有对应的AND镜像实现。

我虽能手动推导部分场景,但缺乏此类优化的通用方案,也不清楚编译器的处理逻辑:是针对双边范围检查组合使用专用转换,还是仅依赖整数转换的通用简化?我查阅了Warren的《Hacker's Delight(第二版)》、技术问答社区及学术文献,暂未找到通用方法。

理想方案要求:
给定两个由编译时常量上下界定义的区间,提供一种算法判断是否可通过AND、XOR(或其他操作,如假设单周期MUL)优化归属检查;若可行,给出具体操作序列与常量。


测试代码示例

#include <cstdio>
#include <cstdlib>
#include <cstdint>

#define CASE (0)

#if (CASE == 0)
bool in_range_1 (uint8_t a)
{
    return ((a >= 0x40u) && (a < 0x50u)) || ((a >= 0x54u) && (a < 0x58u));
}
bool in_range_2 (uint8_t a)
{
    return ((a ^ 0x44u) < 0x14u);
}
#elif (CASE == 1)
bool in_range_1 (uint8_t a)
{
    return ((a >= 0x67u) && (a < 0x70u)) || ((a >= 0x90u) && (a < 0x98u));
}
bool in_range_2 (uint8_t a)
{
    return (((a ^ 0x10u) - 0x77u) < 0x11u);
}
#elif (CASE == 2)
bool in_range_1 (uint8_t a)
{
    return ((a >= 0x10u) && (a < 0x20u)) || ((a >= 0x30u) && (a < 0x40u));
}
bool in_range_2 (uint8_t a)
{
    return ((a & 0xd0u) == 0x10u);
}
#elif (CASE == 3)
bool in_range_1 (uint8_t a)
{
    return ((a >= 0x01u) && (a < 0x21u)) || ((a >= 0x41u) && (a < 0x61u));
}
bool in_range_2 (uint8_t a)
{
    return (((a & 0xbfu) - 0x01u) < 0x20u);
}
#elif (CASE == 4)
bool in_range_1 (uint8_t a)
{
    return ((a >= 0x40u) && (a < 0x50u)) || ((a >= 0x60u) && (a < 0x70u));
}
bool in_range_2 (uint8_t a)
{
    return ((a | 0x2fu) == 0x6fu); // could also be: ((a & 0xd0u) == 0x40u)
}
#else
#error no such CASE
#endif // CASE

int main (void)
{
    uint8_t a = 0;
    do {
        bool ref = in_range_1 (a);
        bool res = in_range_2 (a);
        if (res != ref) {
            printf ("error: a=%02x res=%d ref=%d\n", a, res, ref);
            return EXIT_FAILURE;
        }
        a++;
    } while (a);
    printf ("case %d: test passed\n", CASE);
    return EXIT_SUCCESS;
}

优化效果示例(Case 0)

使用Clang 20.1 -O3为32位RISC-V平台编译Case 0,功能相同的两个函数生成的汇编代码如下:

in_range_1(unsigned char):
        andi    a1, a0, 240
        andi    a0, a0, 252
        addi    a1, a1, -64
        addi    a0, a0, -84
        seqz    a1, a1
        seqz    a0, a0
        or      a0, a0, a1
        ret

in_range_2(unsigned char):
        xori    a0, a0, 68
        sltiu   a0, a0, 20
        ret

内容的提问来源于stack exchange,提问作者njuffa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 09:02:09