无符号整数的快速无分支最大值

Posted

技术标签:

【中文标题】无符号整数的快速无分支最大值【英文标题】:Fast branchless max for unsigned integers 【发布时间】:2013-07-30 12:59:49 【问题描述】:

我从AGGREGATE Magic 中发现了一个快速计算最大值的技巧。唯一的问题是整数,但是我尝试了一些东西,不知道如何为无符号整数制作版本。

inline int32_t max(int32_t a, int32_t b)
 
    return a - ((a-b) & (a-b)>>31);

有什么建议吗?

编辑

不要使用它,因为正如其他人所说,它会产生未定义的行为。对于任何现代架构,编译器都能够从return (a > b) ? a : b 发出无分支条件移动指令,这将比相关函数更快。

【问题讨论】:

等等,你确定这比return a > b ? a : b快吗? 这个功能几乎没用。使用std::max 我的建议是不要假设编译器编写者自己不知道这些技巧。 在 x86 GCC 上为此使用无分支条件移动指令:see here。如果这真的比您的代码慢,我会感到惊讶。 @plasmacel 当具有未定义行为的代码在不同情况下表现出不同的行为时,这并不奇怪——这基本上是意料之中的。 【参考方案1】:

这段代码有什么作用?它采用 a 的值和 a - b 的差值。当然,a - (a - b)b(a - b) >> 31 只是创建一个掩码,如果 a - b 为负数。

这个代码是不正确的,如果你得到一个减法溢出。然而,这与无符号整数的情况相同。因此,如果您对您的代码在整个值范围内都不正确这一事实感到满意,您可以简单地忽略无符号并使用它:

inline uint32_t umax(uint32_t a, uint32_t b) 
    return (uint32_t)max((int32_t)a, (int32_t)b);

【讨论】:

以上是关于无符号整数的快速无分支最大值的主要内容,如果未能解决你的问题,请参考以下文章

有没有一种方法可以在不使用大量分支语句的情况下为无符号整数编写 qsort 比较函数?

C++ - 仅使用无符号整数实现快速排序?

波浪号 C 无符号与有符号整数

NSDecimalNumber 和大的无符号长长(64 位)整数

使用 AVX 的有符号/无符号整数的最小值

带无符号整数的 QSpinBox 用于十六进制输入