简体   繁体   English

是否有自然数的代数表示形式允许并行加法?

[英]Is there any algebraic representation of natural numbers that allow for parallel addition?

Natural numbers can be represented in logarithmic space using a binary representation (here, in little-endian): 自然数可以使用二进制表示形式(在这里为little-endian)在对数空间中表示:

-- The type of binary numbers; little-endian; O = Zero, I = One
data Bin = O Bin | I Bin | End

Addition of a and b can then be implemented, for example, by calling the successor function ( O(log(N)) ) a times on b . 的加成ab然后可以实现,例如,通过调用successor函数( O(log(N)) a上时间b The problem with this implementation is that it is inherently sequential. 这种实现方式的问题在于它本质上是顺序的。 In order to add 2 numbers, suc calls are chained in sequence. 为了添加2个数字, suc调用按顺序链接。 Other implementations of add (such as using carry) suffer from the same issue. add其他实现(例如使用进位)也遇到相同的问题。 It is easy to see that addition couldn't be implemented in parallel with that representation. 很容易看出添加不能与该表示并行执行。 Is there any representation of natural numbers, using algebraic datatypes, which takes logarithm space, and on which addition can be done in parallel? 使用代数数据类型有没有自然数的表示形式?它需要对数空间,并且可以并行进行加法运算?

Code for illustration: 说明代码:

-- The usual fold  
fold :: Bin -> (t -> t) -> (t -> t) -> t -> t
fold (O bin) zero one end = zero (fold bin zero one end)
fold (I bin) zero one end = one (fold bin zero one end)
fold E zero one end       = end

-- Successor of `Bin` - `O(log(N))`
suc :: Bin -> Bin
suc (O bin) = I bin
suc (I bin) = O (suc bin)
suc E       = E

-- Calls a function `a` times
times :: Bin -> (t -> t) -> t -> t
times a f x     = fold a zero one end f where 
    one bin fs  = fs (bin (fs . fs))
    zero bin fs = bin (fs . fs)
    end fs      = x

-- Adds 2 binary numbers
add :: Bin -> Bin -> Bin
add a b = (a `times` suc) b

-- 1001 + 1000 = 0101
main = print $ add (I (O (O (I E)))) (I (O (O (O E))))

There are many parallel adder architectures. 有许多并行加法器体系结构。 An excellent review is given in Thomas Walker Lynch's master's thesis at the university of Texas at Austin, 1996 . 1996年,德克萨斯大学奥斯汀分校的托马斯·沃克·林奇(Thomas Walker Lynch)的硕士学位论文获得了出色的评价。 See section 9.1, where he summarizes the worst case path length. 请参阅第9.1节,其中他总结了最坏情况下的路径长度。

The Lynch and Swartzlander adder (L&S) has a worst case path length of 2*ceil(log4(N))+2, where N is that number of bits. Lynch和Swartzlander加法器(L&S)的最坏情况下路径长度为2 * ceil(log4(N))+ 2,其中N是该位数。 The architecture is presented in their paper A Spanning Tree Carry Lookahead Adder . 他们的论文“生成树携带前瞻加法器”中提出了该体系结构。

You can find excellent explanations about many simple architectures by googling "fast adder". 通过搜索“快速加法器”,您可以找到有关许多简单体系结构的出色解释。

You didn't say that each natural number has to have a unique representation. 您并不是说每个自然数都必须具有唯一的表示形式。 So, here is another option. 因此,这是另一种选择。 (I didn't invent it, but I can't remember what it's called, so I had to reconstruct how it works.) (我没有发明它,但是我不记得它叫什么,所以我不得不重新构造它的工作方式。)

Represent numbers as strings of digits in base 2 like in binary, except that rather than being restricted to the digits 0 and 1, we are additionally allowed to use the digit 2. So for example, the number 2 has two representations, 10 and 2. 以二进制形式将数字表示为以2为底的数字字符串,除了二进制(而不是限于数字0和1)之外,我们还被允许使用数字2。因此,例如,数字2具有两种表示形式,即10和2 。

To add two numbers represented in this way, just add them digitwise without carrying. 要添加以这种方式表示的两个数字,只需将它们按数字方向相加而不带进位即可。 Clearly we can do this efficiently in parallel (with a linear size, constant depth circuit). 显然,我们可以并行高效地执行此操作(使用线性尺寸,恒定深度的电路)。 Well, now we have a problem: the resulting number has the right base-2 value, but its digits won't necessarily be 0, 1 or 2, but might be as large as 4. 好吧,现在我们有一个问题:结果数字具有正确的以2为底的值,但是其位数不一定是0、1或2,而是可能最大为4。

So let's fix that with the following carry propagation pass: Write each digit of the result as a two-digit binary number where the second digit is 0 or 1, and the first digit can be 0, 1 or 2. (So 0 -> 00, 1 -> 01, 2 -> 10, 3 -> 11, 4 -> 20.) Now "carry" the first digit of each these two-digit numbers to the left, leaving behind the second digit, but without performing any other carrying on the result. 因此,让我们通过以下进位传播遍历来解决此问题:将结果的每一位写为两位二进制数,其中第二位为0或1,第一位可以为0、1或2。(所以0-> 00,1-> 01,2-> 10,3-> 11,4->20。)现在将这两位数字的第一个数字“携带”到左侧,留在第二个数字的后面,但不执行任何其他结果。 For example, if we started with the number 例如,如果我们以数字开头

 314102    (perhaps from the original problem of computing 212001 + 102101)

we perform the sum 我们执行总和

11       = 3
 01      = 1
  20     = 4
   01    = 1
    00   = 0
     10  = 2
-------
1130110

The new number has the same base-2 value, and its digits are now in the range 0 to 3, since they are formed from the sum of a digit that was 0, 1 or 2 and a digit that was 0 or 1. Moreover each digit of the result only depends on the corresponding digit and the digit to its right in the number from the step, so this is implementable by another linear size, constant depth circuit. 新数字具有相同的以2为底的值,并且由于由0、1或2的数字与0或1的数字之和构成,因此其数字现在在0到3的范围内。结果的每个数字仅取决于相应的数字和步骤中数字右侧的数字,因此这可以通过另一个线性大小,恒定深度的电路来实现。

This isn't quite good enough, so let's do the same carry propagation pass one more time. 这还不够好,所以让我们再一次进行相同的进位传播。 Now, 4 is no longer a possible input digit, so the digit that we carry can never be 2, only 0 or 1. So this time the procedure will result in a base 2 representation that uses only the digits 0, 1 and 2, which was what we wanted. 现在,4不再是可能的输入数字,因此我们携带的数字永远不能为2,只能是0或1。因此,此过程将导致以2为基数的表示形式仅使用数字0、1和2。这就是我们想要的。 In the example from above, the result will be 1210110 . 在上面的示例中,结果将为1210110 (Of course, any other representation with the same base-2 value would be correct as well.) (当然,其他具有相同基数2值的表示形式也是正确的。)

(For other combinations of base and maximum digit, you might only need one carry propagation pass. For example if you represent numbers in base 3 using the digits 0, 1, 2, 3 and 4, the largest digit appearing in a sum is 8, so both digits involved in the carry propagation pass will be in the range 0, 1, 2 and their sum will already be at most 4.) (对于基数和最大位数的其他组合,您可能只需要进行一次进位传播。例如,如果使用数字0、1、2、3和4表示基数为3的数字,则总和中出现的最大位数为8 ,因此,进位传播通道中涉及的两个数字都将在0、1、2范围内,并且它们的总和将已不超过4。)


Now if you want to do other operations on this representation, such as comparing two numbers for equality, one option is to convert to binary, either serially in linear time, or in parallel by using a fast adder as described in Lior Kogan's answer. 现在,如果您要对该表示形式进行其他操作,例如比较两个数字是否相等,则一种选择是转换为二进制,既可以线性时间串行转换,也可以使用Lior Kogan答案中所述的快速加法器并行转换为二进制。 In fact, converting this representation to binary is essentially equivalent to the problem of adding numbers in binary, since we can consider a representation like 212001 as a "formal addition" 101000 + 111001 . 实际上,将这种表示形式转换为二进制基本上等于在二进制中加上数字的问题,因为我们可以将像212001这样的表示形式视为“形式加法” 101000 + 111001 However, you probably cannot test for equality in this representation in constant depth like you can for binary. 但是,您可能无法像在二进制文件中那样以恒定的深度测试此表示形式中的相等性。 I imagine that the "hardness" in this sense of either addition or equality testing is essential given your other constraints, though I don't know for sure. 我想在给定其他约束的情况下,无论是加法还是相等测试,“硬度”都是必不可少的,尽管我不确定。

One simple way how to describe parallel addition of natural numbers is this: If you look at the full adder circuit , it has 3 input bits and it outputs a 2-bit number saying how many of the input bits were 1. This is also why it's sometimes called 3:2 compressor . 描述自然数并行加法的一种简单方法是:如果看完整的加法器电路 ,它有3个输入位,并且输出一个2位数字,表示多少个输入位为1。这也是为什么有时称为3:2压缩器 From them we can create a circuit that adds 3 binary numbers in parallel to produce 2 binary numbers. 通过它们,我们可以创建一个电路,该电路并行添加3个二进制数以产生2个二进制数。 This is also called a carry-save adder circuit, because instead of propagating the carry bits, we keep them as another, separate number. 这也称为进位保存加法器电路,因为我们没有传播进位,而是将它们保留为另一个单独的数字。 Each number is then (redundantly) represented as a pair of binary numbers. 每个数字然后(冗余地)表示为一对二进制数字。 And when adding k natural numbers, at each step we can reduce triplets to tuples, requiring only O(log k) time steps. 当添加k个自然数时,在每一步我们都可以将三元组减少为元组,只需要O(log k)个时间步长。

But the problem is that if we're only restricted to ADTs, we have a fixed set of constructors, each constructor having a finite number of records. 但是问题是,如果我们仅限于ADT,则我们有一组固定的构造函数,每个构造函数都有有限数量的记录。 So no matter what, the depth of such a structure will be O(log n) . 因此,无论如何,这种结构的深度将为O(log n) And we have to perform O(log n) steps just to traverse the structure. 我们必须执行O(log n)步骤才能遍历结构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM