【问题标题】:Why were bitwise operations slightly faster than addition/subtraction operations on older microprocessors?为什么按位运算比旧微处理器上的加法/减法运算稍快?
【发布时间】:2013-03-18 02:47:50
【问题描述】:

我今天看到了这段摘录:

在大多数较旧的微处理器上,按位运算比加法和加法稍快 减法运算,通常比乘法和除法快得多 操作。在现代架构中,情况并非如此:按位运算通常是 与加法相同的速度(尽管仍比乘法快)。

我很好奇为什么按位运算比旧微处理器上的加法/减法运算稍快。

我能想到的会导致延迟的是,实现加法/减法的电路依赖于几个级别的逻辑门(并行加法器等),而按位运算的电路实现要简单得多。是这个原因吗?

我知道算术和按位运算在现代处理器上都在一个时钟周期内执行,但纯粹谈谈电路的传播时间,理论上现代处理器中的延迟是否仍然存在?

最后,我有一个关于按位移位操作执行的概念性 C 问题:

unsigned x = 1;
x <<= 5;

unsigned y = 0;
y += 32;

xy 都应该保持值 32,但是是否需要 5 单独的左移才能使 x 达到该值(如通过管道)?为了澄清,我纯粹是在询问电路行为而不是时钟周期数。

【问题讨论】:

  • 你的第一个例子给出了零,但这可能是一个错字。您剩下的问题是特定于硬件的,可能与这里无关。
  • @500 我认为了解处理器的工作原理很重要,这样您就可以更好地了解高级代码的运行方式。
  • @kjprice:很公平 - 你会注意到我没有投票结束。
  • @500-InternalServerError 感谢您的提醒,我调整了代码,使其正确。 :)
  • 在旧 CPU 上可能更快的按位运算将是 AND / OR / XOR,而不是移位超过 1。可以为任意移位计数执行 1 个周期移位的桶形移位器比先行进位加法器更昂贵。 (例如,看看 Pentium4:缓慢的转变,但 addxor 一样快。agner.org/optimize/.)不过 Shift-by-1 是一个合理的例子;许多简单的 CPU 只支持移位 1,或者每次计数需要 1 个周期。

标签: c bit-manipulation bitwise-operators cpu-architecture digital-logic


【解决方案1】:

要回答您的最后一个问题,这取决于。一些架构只有 1 的位移(例如 z80),一些架构公开了更大的常量和/或变量的位移,但在内部实现它们作为一堆“位移 1”(例如 old x86 的实现),有一些架构可以在一个周期内移动超过 1,但只有当移位量是一个常数时,有一些架构(例如 x86 的现代实现)使用barrel shifter 并且可以单循环移位一个变量,还有更多的可能。

桶形移位器的电路深度与其可以做的最大移位成对数,不一定是寄存器的宽度 - 它有时比宽度小一,甚至可以想象它更小。

【讨论】:

  • 是的,可能比add 更快的按位运算类似于and / xor。桶形移位器比加法器更贵(或更不重要),或者至少 Pentium4 的设计者是这样决定的。
【解决方案2】:

在任何二进制位运算中,每个输出位仅取决于输入中的两个对应位。在加法运算中,每个输出位取决于输入中的相应位以及右侧的所有位(朝向较低的值)。

例如,01111111 + 00000001 的最左边位为 1,但 01111110 + 00000001 的最左边位为 0。

在最简单的形式中,加法器将两个低位相加并产生一个输出位和一个进位。然后添加接下来的两个最低位,并添加进位,产生另一个输出位和另一个进位。这重复。因此,最高输出位位于加法链的末尾。如果你像旧处理器那样一点一点地进行操作,那么需要时间才能到达终点。

有一些方法可以加快速度,方法是将几个输入位输入更复杂的逻辑安排。但这当然需要更大的芯片面积和更大的功率。

当今的处理器有许多不同的单元来执行各种工作——加载、存储、加法、乘法、浮点运算等等。鉴于当今的能力,与其他任务相比,添加的工作量很小,因此它适合单个处理器周期。

也许从理论上讲,您可以制作一个执行按位运算的处理器比加法运算更快。 (至少在纸面上,有一些奇异的处理器异步运行,不同的单元按照自己的节奏工作。)但是,随着设计的使用,你需要一些固定的周期来协调处理器中的许多事情——加载指令,将它们分派到执行单元,将结果从执行单元发送到寄存器等等。一些执行单元确实需要多个周期来完成它们的工作(例如,一些浮点单元大约需要四个周期来进行浮点加法)。所以你可以混合。但是,在当前规模下,将周期时间缩短以适合按位运算而不适合加法可能不经济。

【讨论】:

    【解决方案3】:

    一些加法实现必须为进位位做一个额外的循环。例如:16 位整数需要在 8 位处理器上执行多条指令。这也适用于转变。但是移位总是可以将高度位移动到下一个字节的较低位。加法必须在额外的一轮中添加低位。

    【讨论】:

      【解决方案4】:

      加法(你通常可以免费减法)的复杂之处在于存在令人讨厌的进位问题。

      因此,您最终会得到 N 次 Full-Adders 的幼稚解决方案,其中 N 是您的 ALU 的位数。

      这些讨厌的载体意味着你有很多传播延迟。而且,由于一次结转可能会使整个结果不准确,因此您最终不得不等待相当长的时间来等待所有的结转值,而反过来,链上的所有其他全加器都必须等待结算。

      有很多方法可以绕过这个特定的瓶颈,但没有一种方法像全加器链那样简单或资源便宜。 (最快的是在硅中实现的查找表)

      如果您想了解更多详情,您可能需要在http://electronics.stackexchange.com 上提问

      【讨论】:

      • 如果您考虑如何实现查找表,它的解复用器在 2^N 门之一中选择一个与来自另一个操作数的信号组合的信号,这些门再次馈入多路复用器,你会意识到一个完全组合的加法器只是一个查找表,经过高度优化以消除所有重复的逻辑。
      • @BerndJendrissek 在某个时刻,一切都归结为一个查找表。另见"The tactical nuke of logic design"
      【解决方案5】:

      按位运算符的执行时间更短,因为

      • 处理器采用一条指令执行按位操作,并且(让 比如说)需要一个执行周期,另一方面,其他算术指令(特别是乘法和除法)需要更多的执行周期
      • 大多数情况下,按位运算在一个寄存器中执行,而其他算术指令则需要处理多个寄存器

      这就是为什么移位比其他算术运算更快的原因

      【讨论】:

      • and / xor / or 这样的位运算也总是很快。当然 mul/div 很贵,但这是在询问按位与 add/sub。
      【解决方案6】:

      这是我从汇编类的介绍中看到的。但是移位只是处理器可以执行的最快指令。加减法需要一些指令来执行。我想现代处理器会得到更好的优化。

      想必有人可以更准确、更彻底地回答这个问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-31
        • 2018-08-03
        • 1970-01-01
        • 1970-01-01
        • 2016-11-15
        • 1970-01-01
        • 1970-01-01
        • 2018-02-25
        相关资源
        最近更新 更多