【发布时间】:2010-07-30 16:21:48
【问题描述】:
在任意长度的数组中找到第一个未设置位的位偏移的最快/最干净的方法是什么?
假设您的函数原型类似于size_t first_unset_bit(char unsigned const *buf, size_t bit_count, size_t start_bit);,并且它可能在同一个缓冲区上快速连续调用多次。如果你能给出更好的原型,请说明理由。
如果您使用任何程序集,请提供将在 core2 或更高版本上运行的 x86 示例。我将把答案奖励给提供速度和美感的最佳组合的解决方案。
更新0
这是我的幼稚实现。我不知道它是否真的正确,它还没有在实时系统中使用。
static size_t first_unset_bit(char unsigned const *buf, size_t bit_count, size_t start_bit)
{
for (; start_bit < bit_count; ++start_bit)
{
size_t buf_index = start_bit / CHAR_BIT;
int bit_index = start_bit % CHAR_BIT;
if (!((buf[buf_index] >> bit_index) & 1))
return start_bit;
}
return -1;
}
【问题讨论】:
-
数组是否可能包含大量未设置位或大量设置位? IE。最常见的情况是设置所有位、未设置位、设置大多数位、未设置大多数位等。
-
哈哈,不,这不是作业。常见的情况将倾向于大部分未设置:设置大的连续块,这里和那里有不同大小的孔(大多数较小)。缓冲区是文件系统中块分配的位图。
-
另外,目标系统是什么字节序(如果这很重要)? IE。如果前 8 个字节是 128,255,255,255,255,255,255,255,那么它的“位偏移”是多少? 0 或 7 还是完全不同的?
-
由于它们大部分未设置,因此任何假设大部分已设置的优化都是无用的,因为在找到未设置位之前您似乎不会循环太远。我错过了什么吗?
-
@James Black,很怀疑,但这就是我问题的重点。这些天我不在 C 或汇编中工作,但我想最常见的情况会决定哪些优化是有意义的,哪些没有。 “大部分未设置”可能会排除查看 32 或 64 位值(基于 CPU)的初始循环,因为跳过 4 或 8 个字节的“全部设置”位将比查看每个单独的字节快得多.我只是认为这样一个问题的答案很重要。
标签: c performance algorithm optimization bit-manipulation