使用逻辑和/或无条件/分支
Use of logical AND/OR without conditional/branching
我正在尝试编写一个函数,该函数在避免使用分支或条件的同时计算一些位标志:
uint8_t count_descriptors(uint8_t n)
{
return
((n & 2) && !(n & 1)) +
((n & 4) && !(n & 1)) +
((n & 8) && !(n & 1)) +
((n & 16) && !(n & 1)) +
((n & 32) && 1 ) +
((n & 64) || (n & 128)) ;
}
位零不是直接计数的,但是仅在未设置位0时才考虑位1-4,位5被视为无条件,位6-7只能计数一次。
但是,我知道布尔值&&和||使用短路评估。这意味着他们在此类示例中看到的那样,它们会创建一个条件分支:如果从第一个子表达评估结果短路,则不会执行第二个子表达中的代码的if( ptr != nullptr && ptr->predicate())
。
问题的第一部分:我需要做任何事情吗?由于这些是纯粹的算术操作,没有副作用,因此编译器会创建条件分支吗?
第二部分:我知道位于布尔运算符不会简短评估,但是钻头不排队的唯一问题。掩盖n位的结果为2^n或零。
制作诸如(N& 16)等表达式的最佳方法是什么?
我假设"只有"位6-7"才能计数一次。
在这种情况下,类似的东西应该起作用
uint8_t count_descriptors(uint8_t n)
{
uint8_t retVar;
retVar = (n&1)*(n&2 >> 1) +
(n&1)*(n&4 >> 2) +
(n&1)*(n&8 >> 3) +
(n&1)*(n&16 >> 4) +
(n&32 >> 5) +
(int)((n&64 >> 6) + (n&128 >> 7) >= 1)
return retVar;
}
制作诸如(N& 16)等表达方式的最佳方法是什么 到1或0?
通过正确移动所需的位数:(n>>4)&1
或(n&16)>>4
。
我可能会使用一个查找表,要么适用于所有256个值,或者至少适用于4的组。
nbits[16]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
//count bits 1..4 iff bit 0 is 0, bit 5 always, and bit 6 or 7
return (!(n&1) * nbits[(n>>1)&0xF]) + ((n>>5)&1) + (((n>>6)|(n>>7))&1)
我认为将(N& 16)转换为0或1的最干净的方法就是仅使用int(bool(n & 16))
。如果您在算术表达式中使用了int
的铸件(例如bool(n & 2) + bool(n & 4)
)。
对于您的计数位设置的功能,我建议使用GCC上的__builtin_popcount和MSVC上的__popcnt使用popcount intinsic函数。以下是我对您描述的功能的理解,更改为使用Popcount。
f(n & 1)
{
//clear out first 4 bits and anything > 255
n &= 0xF0;
}
else
{
//clear out anything > 255 and bottom bit is already clear
n &= 0xFF;
}
return __builtin_popcount(n); //intrinsic function to count the set bits in a number
这与您写的功能不太匹配,但希望从这里您得到这个想法。
- IPC使用多个管道和分支进程来运行Python程序
- 如何删除peer if else分支中的冗长句子
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 如何正确地将分支添加到已存在的树中
- 如何将分支添加到已存在的TTree:ROOT
- 如何删除 LLVM 中的不规则分支?
- 如果以下行不包含决策或分支,GDB 无法单步跳过函数
- 函数指针与条件分支
- 分支未在 Linux 上采用
- 如何删除分支因子不一致的树,最大为 30,40
- std::shared_ptr vs std::make_shared:意外的缓存未命中和分支预测
- 更改 git 分支名称后,在项目的 Visual Studio 代码中丢失智能感知(建议,转到定义C++
- 条件分支评估
- 是否可以使用函数指针数组来删除分支
- 基于派生类型的编译时行为分支
- L 系统树无法正确分支
- Antlr4 C++访问模棱两可的分支
- 如何为不同的分支使用不同的 Xcode 版本(或具有不同 Clang 版本的最新 Xcode)?
- 使用逻辑和/或无条件/分支
- 为什么clang和gcc在循环中重复代码和分支与无条件跳转