模数运算符为什么慢?

时间:2015-01-16 05:31:17

标签: modulo integer-division cpu-speed programming-pearls

从“编程珍珠”一书中解释(关于旧机器上的c语言,因为本书是从90年代后期开始的):

整数算术运算(+-*)可能需要大约10纳秒,而%运算符需要100纳秒。

  • 为什么会有那么大的差异?
  • 模数运算符如何在内部工作?
  • 就时间而言是否与除法(/)相同?

1 个答案:

答案 0 :(得分:13)

模数/模运算通常被理解为余数运算的整数等价 - 副作用或与除法相对应。

除了一些退化情况(除数是操作基数的幂 - 即大多数数字格式的2的幂),这和整数除法一样昂贵!

所以问题是,为什么整数除法如此昂贵?

我没有时间或专业知识来数学分析这个,所以我会吸引小学数学:

考虑笔记本中的工作线数(不包括输入):

  • 平等:(布尔运算)基本上没有 - 在计算机“大O”术语中这是已知的O(1)
  • 另外:两个,左到右工作,输出一行,进位一行。这是O(N)操作
  • 长乘法:n *(n + 1)+ 2:每个数字产品两条线(一条用于总数,一条用于进位)加上最终总数和进位数。所以O(N ^ 2)但是具有固定的N(32或64),并且它可以在硅中流水线化到小于那个
  • 长划分:未知,取决于参数大小 - 它是递归下降,有些实例比其他实例下降得更快(1,000,000 / 500,000需要的线数少于1,000 / 7)。此外,每个步骤基本上是一系列乘法,以隔离最接近的因素。 (尽管存在多种算法)。感觉像是具有可变N
  • 的O(N ^ 3)

所以简单来说,这应该让你感觉为什么除法和模数更慢:计算机仍然必须以与你在小学时相同的逐步方式进行长时间划分。

如果这对你没有意义;你可能已经把学校的数学培养成比我的更现代(30多年前)。


上面用作O(某事物)的Order / Big O表示法根据其输入的大小表示计算的复杂性,并表达关于其执行时间的事实。 http://en.m.wikipedia.org/wiki/Big_O_notation

O(1)以恒定(但可能很大)的时间执行。 O(N)花费的时间与其数据的大小相同 - 因此,如果数据是32位,则需要32倍于步骤的O(1)时间来计算其N个步骤中的一个,并且O(N ^ 2) N次N(N平方)取其N步的时间(或者对于某些常数M可能是N次MN)。等


在上述工作中,我使用了O(N)而不是O(N ^ 2)来添加,因为第一个输入的32位或64位是由CPU并行计算的。在假设的1位机器中,32位加法运算将是O(32 ^ 2)并且改变。同样的订单减少也适用于其他操作。