【发布时间】:2015-09-02 10:54:20
【问题描述】:
我有这个函数,给定Gray code,返回下一个格雷码。你可以找到关于它如何工作的更完整的解释here。问题是我想让这个递增函数模块化,以便递增对应于UINT_MAX 的格雷码返回对应于0 的格雷码(分别是最高有效位和0)。由于这不是默认行为,因此我为这种特殊情况添加了检查。这是完整的算法:
unsigned next_gray(unsigned gray)
{
static const unsigned msb
= 1u << (CHAR_BITS - sizeof(unsigned) - 1u);
// gray is odd
if (__builtin_parity(gray))
{
if (__builtin_expect(gray == msb, false))
{
return 0u;
}
else
{
unsigned y = gray & -gray;
return gray ^ (y << 1u);
}
}
// gray is even
return gray ^ 1;
}
所以,实际的问题实际上是关于分支预测的。我经常读到__builtin_expect 仅在确实可能选择或不太可能选择分支时使用,常见示例是在没有错误的情况下加速程序。
考虑到我没有处理错误情况,我不确定使用__builtin_expect 进行这样的边界检查是否是个好主意。这是使用__builtin_expect 的好地方吗?或者增加最大值是一种足够常见的操作来欺骗分支预测?
注意:与往常一样,cmets 和答案会突出显示我的问题中不清楚的内容 :)
我将提供更多背景信息:此函数旨在成为库的一部分,为成为库而开发,并且不被任何已知的实际项目使用。因此,添加__builtin_expect 意味着我希望人们主要增加其他值而不是最大值;手头没有任何实际项目,我想知道这是否是一个安全的假设。
【问题讨论】:
标签: c branch-prediction gray-code