【问题标题】:efficient way to split ONE bitstream according to many masks?根据许多掩码拆分一个比特流的有效方法?
【发布时间】:2013-11-28 04:07:37
【问题描述】:

我正在尝试制作一个Inverse Multiplexer,它可以根据一些掩码将一个比特流分成多个。

这是想法示例

这是一个24位的流,每个字母代表1位:

abcdefgh ijklmnop qrstuvwx

给定三个个掩码,每个掩码没有共同点,如果 & 一起是 [1,1,1,1,1,1,1,1]

[1, 1, 0, 0, 1, 0, 0, 0]
[0, 0, 1, 0, 0, 0, 1, 1]
[0, 0, 0, 1, 0, 1, 0, 0]

像这样将这些掩码应用于流

stream1 = ab__e___ ij__m___ qr__u___
stream2 = __c___gh __k___op __s___wx
stream3 = ___d_f__ ___l_n__ ___t_v__

所以原始比特流被分成三个比特流,如下所示:

stream1 = abeijmqru
stream2 = cghkopswx
stream3 = dflntv

以上只是一个例子,我需要对给定的比特流应用任意数量的掩码。保证口罩彼此之间具有OR 的零结果。将AND 应用于所有掩码,结果为 ONE。所有掩码的长度相同。

我写了一个愚蠢的版本来蛮力这个想法,基本上是在循环中逐位移动。认为它肯定没有效率。

我查看了这个http://graphics.stanford.edu/~seander/bithacks.html

没有线索。任何人都有更好的想法如何改善这一点? (在 x86 机器上)

【问题讨论】:

  • 如果您能解释您想要达到的目标,改进什么,将会非常有帮助?这些面具将如何使用?此外,您正在讨论位掩码,但该示例包含字符(每个字符由 16 位表示)。你用的是什么编程语言?
  • @alfasin 是我制作Inverse Multiplexer 的个人编程实验。我将其添加到问题中。
  • @alfasin 我觉得这些字母只是每个位的指示符
  • @PeterGibson 坏主意 - 如果您正在处理位和字节,请坚持使用它,否则只会令人困惑。
  • @alfasin 我认为这是说明掩码中位位置的好方法,但可以更清楚地解释

标签: bit-manipulation bit bitmask bitstream


【解决方案1】:

我想既然你只有一个对应于单个“流”的位,那么你可以同时移动所有这些并查看“这属于哪个流”。这将允许适度数量的并行实现——尽管这将在一定程度上取决于架构和掩码的大小,这将是多么有效。它还取决于您希望执行此操作的频率 - 一定数量的预计算将使后续运行更有效率。听起来确实有点蛮力。可能不会比你已经做过的更好。

当然,有一个可爱的问题Extracting bits with a single multiplication(我写了公认的答案……),它提出了一种通过单次乘法从较大数字中提取某些位的方法。这种方法确实有一个缺点,即您不能对任意数量的设置位执行此操作 - 两者之间需要有多个空格。

原则上,这可以通过重复该过程两次或更多次,并在其间应用额外的掩码来解决。让我们看看这仅适用于上述问题中的第一个掩码。

mask1 = 11001000
num =   abcdefgh
temp = num & mask1 = ab..e...
magic = 4 + 1
answer =     ab..e... 
           ab..e..... + 
           ------------
           ababe.e...
mask2 =    0011100000
ans & mask = abe.....

这会将您想要的三位数字放入前三位,使用掩码乘掩码(3 次操作)。对于八位数字来说效率不是很高;但你可以将其扩展为 32 位数字,然后它开始看起来更有趣。

【讨论】:

  • 经过认真琢磨,你的答案绝对是最好的!乘法技巧摇滚!谢谢!
【解决方案2】:

如果每个位只映射到一个输出流,我认为定义这些位分配给哪些输出流比使用掩码更有意义。例如,您的示例掩码

[1, 1, 0, 0, 1, 0, 0, 0]
[0, 0, 1, 0, 0, 0, 1, 1]
[0, 0, 0, 1, 0, 1, 0, 0]

将改为表示为输出流以将当前位分配给

[0, 0, 1, 2, 0, 2, 1, 1]

还有一些伪代码将其绑定在一起

stream_order = [0, 0, 1, 2, 0, 2, 1, 1]
index = 0
for bit in input_stream:
    n = stream_order[index]
    output_streams[n].push(bit)
    index++
    index %= len(stream_order)

【讨论】:

  • 这与我的做法非常相似,但是,恕我直言,output_streams[n].push(bit) 可以通过一些巧妙的技巧来改进。
猜你喜欢
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-18
  • 1970-01-01
相关资源
最近更新 更多