内部计算64位整数中的尾随零位?

时间:2013-12-23 16:16:20

标签: c++ c performance bit-manipulation intrinsics

这是关于位操作的一些先前问题的后续跟进。我修改了this site中的代码来枚举设置了N位K的字符串(x是设置了K位的当前int64_t,并且在此代码的末尾,它是按字典顺序排列的下一个整数,带有K位集):

int64_t b, t, c, m, r,z;
b = x & -x;
t = x + b;
c = x^t;
// was m = (c >> 2)/b per link
z = __builtin_ctz(x);
m = c >> 2+z;
x = t|m;

使用__builtin_ctz()的修改只要最低有效位在x的下DWORD中就可以正常工作,但如果不是,则完全中断。这可以通过以下代码看出:

for(int i=0; i<64; i++) printf("i=%i, ctz=%i\n", i, __builtin_ctz(1UL << i));

打印GCC版本4.4.7:

i=0, ctz=0
i=1, ctz=1
i=2, ctz=2

...

i=30, ctz=30
i=31, ctz=31
i=32, ctz=0

或者对于icc版本14.0.0类似的东西(除了i> 32给出随机结果,而不是零)。在两种情况下使用除法而不是移动2 + z都有效,但是在我的Sandy Bridge Xeon上慢了大约5倍。我还应该使用64位其他内在函数,还是必须使用内联汇编程序?

谢谢!

1 个答案:

答案 0 :(得分:7)

__builtin_ctz接受类型为unsigned int的参数,在大多数平台上为32位。

如果long为64位,则可以使用__builtin_ctzl unsigned long。或者您可以使用__builtin_ctzll unsigned long long - 在这种情况下,您应该使用1ULL << i代替1UL << i