我正在寻找一个计数器的优化实现,可能类似于格雷码,这将允许我快速遍历bitliced数组中的数字。
假设我有阵列:
_m256 header[640];
我需要在位608 - 639中不断更改计数器.256位中的每一位代表一个单独的并行计数器。
'增量'操作最多需要31次操作:AND计算进位,XOR计算值,对每个位置重复。
格雷码应该只需要xor,但我不知道计算索引的有效方法 - 它似乎需要多达31个操作来确定位位置。
理想情况下,我想要一个需要少量ALU操作的计数器来确定要更改的位。有谁知道有用的东西吗?
答案 0 :(得分:1)
LRS可以使用少量的XOR生成包含所有非零数字1..2 ^ n-1的序列,但是移位每个阶段留下的所有位。 http://www.ee.unb.ca/cgi-bin/tervo/sequence.pl?binary=11111有一些信息。 XOR的数量取决于抽头的数量。有一个32位的LRS配置列表,http://www.newwaveinstruments.com/resources/articles/m_sequence_linear_feedback_shift_register_lfsr/32stages.txt只有很少的点击。当然,生成的序列是乱序的 - 它显然是随机的。
答案 1 :(得分:0)
有趣的论文:The Gray Code。 (这是PDF)
PDF的第16页包含一个用于查找要切换的位的算法。在一般情况下,它需要32次操作来确定要更改的位。如果您可以从计数器中省略一位(这将使其成为一个有效的31位计数器),您可以使平均增量时间减少操作。
由于只要奇偶校验为偶数就会切换低位,如果可以保留奇偶校验位,则每隔一个递增操作只需切换低位。当然,您可以在每次操作时切换奇偶校验位。
当奇偶校验为奇数时,您只需要执行找到要切换的位的算法部分。但既然您已经知道奇偶校验是奇数,那么您不必检查每一位。当您找到符合条件的位时,您可以停止。
我对SIMD不太熟悉,如果你有任何方法可以优化它。
那就是说,我不清楚这样的事情会比“常规”二进制计数器所采取的“最多31次操作”有所改善。再一次,一半的操作只需要一次迭代。似乎使用格雷码的主要优点是只需要一次写入内存(两次,如果你使用上面的奇偶校验位方法),而另一种方法可能需要最多32次写入内存。
答案 2 :(得分:0)
您可以通过这种方式实现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。