我是c++的新手,我正试图编写一个函数,该函数将弹出最低有效位,然后返回该位的索引。有没有一种方法可以在不创建临时变量的情况下做到这一点?
现在我有一个查找索引的函数和一个显示位的函数,但我想把两者结合起来。
inline int LSB(uint64_t b) {
return int(_tzcnt_u64(b));
}
inline uint64_t popLSB(uint64_t b, int index) {
return (b ^ (1ui64 << LSB(b)));
}
我唯一的想法是需要一个临时索引变量,这感觉很糟糕。
int bestIdea(uint64_t *b) {
int index = int(_tzcnt_u64(*b));
*b ^= (1ui64 << index);
return index;
}
有更好的方法吗?如果有任何其他不必要的或愚蠢的代码,我很乐意接受建议,这是我的第一个项目,我不确定几乎任何部分。
使用临时变量没有错。然而,现代体系结构是超标量和无序的,所以为了更好地适应它们,你应该只对返回值使用它,而不要用它来清除最低有效位,以避免不必要的依赖链
int popLsbAndReturnIndex(uint64_t *b) {
int index = int(_tzcnt_u64(*b));
*b &= *b - 1; // Not depend on the previous line
return index;
}
现在我们有了更好的指令级并行性,体中的两行可以并行运行
当然,一些非常聪明的编译器可以识别模式并将原始代码编译为不依赖的版本,但是没有人可以保证
更多建议:
- 使用
std::countr_zero
代替_tzcnt_u64
如果你有c++ 20或更高版本 - 使用引用代替指针
结果如下
int bestIdea(uint64_t &b) {
auto index = std::countr_zero(*b);
b &= b - 1;
return index;
}