在仅有__builtin_clz
给出错误答案的情况下,只有一种情况。我很好奇是什么导致了这种行为。
当我使用文字值0时,我总是得到32的期望值。但是0作为变量将产生31。为什么存储值0的方法很重要?
我参加了一个建筑课程,但是不了解差异化的程序集。看起来,当给定文字值0时,即使不进行优化,该汇编总会以某种方式始终具有32个硬编码的正确答案。使用-march = native时,用于计算前导零的方法也不同。
This post关于用__builtin_clz
模拟_BitScanReverse
和行bsrl %eax,%eax
似乎暗示反向位扫描不适用于0。
+-------------------+-------------+--------------+
| Compile | literal.cpp | variable.cpp |
+-------------------+-------------+--------------+
| g++ | 32 | 31 |
| g++ -O | 32 | 32 |
| g++ -march=native | 32 | 32 |
+-------------------+-------------+--------------+
literal.cpp
#include <iostream>
int main(){
int i = 0;
std::cout << __builtin_clz(0) << std::endl;
}
variable.cpp
#include <iostream>
int main(){
int i = 0;
std::cout << __builtin_clz(i) << std::endl;
}
g ++的差异-S [名称] -o [名称]
1c1
< .file "literal.cpp"
---
> .file "variable.cpp"
23c23,26
< movl $32,%esi
---
> movl -4(%rbp),%eax
> bsrl %eax,%eax
> xorl $31,%eax
> movl %eax,%esi
g ++的差异-march =本机-S [名称] -o [名称]
1c1
< .file "literal.cpp"
---
> .file "variable.cpp"
23c23,25
< movl $32,%eax
> lzcntl %eax,%esi
g ++的差异-O -S [名称] -o [名称]
1c1
< .file "literal.cpp"
---
> .file "variable.cpp"