对于给定first
长度的位向量bitnum
(<32),我需要遍历所有相同长度的字典顺序连续位向量。
例如,如果first
是 011001(二进制)并且bitnum
是 6,那么所有连续的都是:011011、011101、011111、111001、111011、111101、111111。另外,我也需要迭代 011001。
我的意思是字典顺序:
- 如果 in 的第 i 位
first
是 '1',那么 的第 i 位next
必须是 '1' - 如果第 i 位
first
是 '0',那么第 i 位next
可以是 '0' 或 '1'
生成此类位向量的最快方法是什么?
现在我使用这个未优化的代码,它通过生成所有可能的位向量来工作,并检查每个向量是否遵循first
字典中给定的方式。
uint32_t loop_over_all_lex_succ(int bitnum, uint32_t first) {
uint32_t next = first;
uint32_t tmp;
do {
target_function(next);
do {
next++;
tmp = (~first|next); // sets the 0 bit at offset iff `next` has a 0 bit and `first` has 1
tmp = ~tmp; // invert tmp; now all invalid bits are marked with '1'
tmp = tmp & ((1<<bitnum)-1); // mask the tmp with target bit number
} while( (next < (1<<bitnum)) && tmp );
} while ( next < (1<<bitnum) );
}
我认为,如果代码只生成连续的位向量,它会更快。
First
向量是具有该位长度的任何可能的向量。
生成向量的顺序可以不同。
如果你想对这个函数或你的版本进行基准测试,有一个小的基准测试器,只需添加一个循环.. 函数代码:
#include <stdio.h>
#include <stdint.h>
uint32_t count =0;
void target_function(uint32_t a) { count++; }
/* loop_over_all_lex_succ() here */
int main() {
uint32_t f;
int bitnum=16; // you can increase it up to 31
for(f=0;f<(1<<bitnum);f++)
loop_over_all_lex_succ(bitnum,f);
printf("bits: %d, count of pairs: %u\n",bitnum,count);
}
例如,对于 bitnum=16,此代码在我的 PC 上运行 6 秒。我需要使用具有更高位数的此功能,最多 31。
请帮我优化loop_over_all_lex_succ
。