如何快速扫描完全相同的重复二进制模式的 128 位组,例如 010101... 或 0011001100...?
我有许多 128 位块,并希望查看它们是否与 1 的数量等于 0 的数量的模式匹配,例如 010101 .... 或 00110011 ... 或 0000111100001111 ... 但不是 001001001。 ..
问题是模式可能不会从它们的边界开始,所以模式 00110011.. 可能以 0110011... 开始,并且也会以 1 位移动结束(注意 128 位不是循环的,所以 start 不会加入结尾)
010101... 情况很简单,就是 0xAAAA... 或 0x5555.... 但是随着模式变长,排列变长。目前我使用重复移位值,例如这个问题中概述的最快的方法来扫描位流中的位模式,但更快的方法会很好,因为我在这个例程中花费了所有 CPU 的 70%。其他海报有针对一般情况的解决方案,但我希望我的模式的对称性质可能会带来更优化的东西。
如果有帮助,我只对最长 63 位的模式感兴趣,并且对 2 种模式(0101...00110011...0000111100001111...等)的力量最感兴趣,而 5 个 1/5 个零之类的模式是目前,这些非幂 2 序列小于 0.1%,因此如果它有助于常见情况更快地进行,则可以忽略。
完美解决方案的其他限制条件是汇编指令数量少,没有非常随机的内存访问(即,大彩虹表并不理想)。
编辑。更精确的图案细节。
我最感兴趣的是 0011 和 0000,1111 和 0000,0000,1111,1111 和 16 个零/一和 32 个零/一(逗号仅供阅读)的模式,其中每个模式在 128 位内连续重复。重复部分的长度不是 2、4、8、16、32 位的模式没有那么有趣,可以忽略。(例如 000111...)
扫描的复杂性在于模式可以从任何位置开始,而不仅仅是在 01 或 10 过渡处。因此,例如,以下所有内容都将匹配 00001111... 的 4 位重复模式...(为了便于阅读,每 4 位逗号)(省略号表示重复相同)
0000,1111... 或 0001,1110... 或 0011,1100... 或 0111,1000... 或 1111,0000... 或 1110,0001... 或 1100,0011... 或1000,0111
在 128 位内,需要重复相同的模式,存在两种不同的模式是不感兴趣的。例如,这不是一个有效的模式。0000,1111,0011,0011... 因为我们已经从 4 位重复变为 2 位重复。
我已经验证了 1 的数量是 64,这对于所有 2 次方模式都是如此,现在需要确定有多少位组成重复模式(2、4、8、16、32)以及模式是多少转移了。例如,模式 0000,1111 是 4 位模式,移位了 0。而 0111,1000... 是 4 位模式,移位了 3。