在并行位片代码中实现快速计数器

Posted

技术标签:

【中文标题】在并行位片代码中实现快速计数器【英文标题】:Implementing fast counter in parallel-bitsliced code 【发布时间】:2011-05-27 19:28:26 【问题描述】:

我正在寻找计数器的优化实现,可能类似于格雷码,这将允许我快速遍历位切片数组中的数字。

假设我有数组:

_m256 header[640];  

我需要不断更改第 608 - 639 位的计数器。256 位中的每一个都代表一个单独的并行计数器。

“增量”操作最多需要 31 次操作:AND 计算进位,XOR 计算值,每个位置重复。

格雷码应该只需要异或,但我不知道计算索引的有效方法 - 它似乎需要多达 31 次操作来确定位位置。

理想情况下,我想要一个需要少量 ALU 操作来确定要更改的位的计数器。有谁知道一些有用的东西吗?

【问题讨论】:

我不太清楚您要做什么。您说“256 位中的每一个都代表一个单独的并行计数器”。 1 位计数器仅在 0、1、0、1、... 之间振荡,进位只是反转值。要计算进位,在“递增”之前,您只需获取每个计数器的当前值。要计算新值,你只是'不是'计数器。这可以通过转换为大数据类型(例如 int)并采用按位补码(~value)同时使用多个计数器来完成。 有 256 个并行计数器,每个 32 位。 Counter0 使用 header[608]..header[639] 的第 0 位,counter255 使用 header[608]..[639] 的第 255 位。 【参考方案1】:

LRS 可以生成一个包含所有非零数字 1..2^n-1 的序列,使用少量 XOR,但在每个阶段将所有位左移。 http://www.ee.unb.ca/cgi-bin/tervo/sequence.pl?binary=11111 有一些信息。 XOR 的数量取决于抽头的数量。在http://www.newwaveinstruments.com/resources/articles/m_sequence_linear_feedback_shift_register_lfsr/32stages.txt 有一个 32 位 LRS 配置列表,只需轻按几下即可。当然生成的序列是乱序的——它显然是随机的。

【讨论】:

【参考方案2】:

有趣的论文:The Gray Code。 (这是一个PDF)

PDF 的第 16 页包含用于查找要切换的位的算法。在一般情况下,它需要 32 次操作来确定要更改哪个位。如果您可以从计数器中节省一位(这将使其有效地成为 31 位计数器),您可以使 平均 增量时间需要更少的操作。

由于只要奇偶校验位为偶数就会切换低位,如果您可以保留一个奇偶校验位,那么每个其他递增操作将只涉及切换低位。当然,您可以在每次操作时切换奇偶校验位。

当奇偶校验为奇数时,您只需执行算法中找到要切换的位的部分。但是由于您已经知道奇偶校验是奇数,因此您不必检查每一位。找到满足条件的位就可以停下来了。

我对 SIMD 不够熟悉,无法说明是否有任何方法可以优化它。

也就是说,我不清楚这样的事情是否会比“常规”二进制计数器所采取的“最多 31 次操作”有所改进。同样,您的一半操作只需要一次迭代。似乎使用格雷码的主要优点是只需要一次写入内存(如果您使用上面的奇偶校验位方法,则需要两次),而另一种方法可能需要最多 32 次写入内存。

【讨论】:

计算准确的索引可能会因为分支惩罚而变慢。我不需要覆盖整个范围,因此状态较少的计数器就可以了。【参考方案3】:

这样可以实现256个并行Linear Shift Feedback Register(base==608)

calculate x := header[base+0] XOR header[base+1] XOR header[base+21] XOR header[base+31]
move all elements header[base]...header[base+30] to header[base+1]...header[base+31]
set header[base] := x

这将有 2^32-1 个不同的状态。如果 2^31-1 足够,请使用抽头 27 和 30 而不是 0、1、21、31。魔术数字来自http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf。

【讨论】:

以上是关于在并行位片代码中实现快速计数器的主要内容,如果未能解决你的问题,请参考以下文章

如何在javascript中实现多个项目的计数?

Bootstrap:在标题(导航栏)中实现类似 facebook 的通知作为子菜单,而不仅仅是计数器

在 SQLite 数据库中实现诸如引用计数之类的东西

在HAL for STM32中实现单按、长按和双按功能

如何在Clojure中实现整数的计数排序?

如何在django模板中实现列表迭代[重复]