Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么在较旧的微处理器上,按位运算比加法/减法运算略快?_C_Bit Manipulation_Bitwise Operators_Cpu Architecture_Digital Logic - Fatal编程技术网

C 为什么在较旧的微处理器上,按位运算比加法/减法运算略快?

C 为什么在较旧的微处理器上,按位运算比加法/减法运算略快?,c,bit-manipulation,bitwise-operators,cpu-architecture,digital-logic,C,Bit Manipulation,Bitwise Operators,Cpu Architecture,Digital Logic,我今天看到了这段摘录: 在大多数较旧的微处理器上,按位运算比加法和加法略快 减法运算通常比乘除运算快得多 操作。在现代体系结构中,情况并非如此:按位操作通常是 与加法相同的速度(尽管仍然比乘法快) 我很好奇为什么在老式微处理器上,按位运算比加法/减法运算稍微快一点 我所能想到的可能导致延迟的原因是,实现加法/减法的电路依赖于几个级别的逻辑门(并行加法器等),而按位操作的电路实现要简单得多。这是原因吗 我知道算术运算和位运算在现代处理器上都是在一个时钟周期内执行的,但单纯地说电路的传播时间,在现代

我今天看到了这段摘录:

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

我很好奇为什么在老式微处理器上,按位运算比加法/减法运算稍微快一点

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

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

最后,我对按位移位操作的执行提出了一个概念性的C问题:

unsigned x = 1;
x <<= 5;

unsigned y = 0;
y += 32;
无符号x=1;

x这是我从组装课的介绍中看到的。但移位几乎是处理器可以执行的最快指令。加法和减法需要一些指令来执行。我认为现代处理器的优化效果更好


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

在任何二进制位操作中,每个输出位只取决于输入中的两个对应位。在加法操作中,每个输出位取决于输入中的对应位和右侧的所有位(朝较低的值)

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

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

有一些方法可以通过将多个输入位输入到更复杂的逻辑排列中来加快速度。但这当然需要更多的芯片面积和更大的功耗

今天的处理器有许多不同的单元来执行各种工作负载、存储、加法、乘法、浮点运算等等。考虑到目前的功能,与其他任务相比,执行add的工作量很小,因此它适合单处理器周期


从理论上讲,也许你可以制造一个比加法运算更快的处理器。(至少在纸面上,有一些异国情调的处理器是异步运行的,不同的单元以自己的速度工作。)然而,在使用中的设计中,您需要一些固定的周期来协调处理器加载指令中的许多事情,将它们分配给执行单元,将结果从执行单元发送到寄存器,等等。某些执行单元确实需要多个周期来完成其作业(例如,某些浮点单元需要大约四个周期来完成浮点加法)。这样你就可以混音了。但是,使用当前的比例,使循环时间更小,以便适合按位操作而不是加法,这可能不经济。

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

  • 处理器接收一条指令执行逐位运算,并(让 假设)执行一个执行周期,另一方面,其他算术指令(特别是乘法和除法)执行更多的执行周期
  • 大多数情况下,逐位运算是在一个寄存器中执行的,而处理多个寄存器所需的其他算术指令

这就是为什么移位位比其他算术运算快的原因。加法(通常可以免费得到减法)的复杂之处在于存在令人讨厌的进位问题

所以,最终的简单解决方案是N倍,其中N是ALU的宽度

这些讨厌的携带意味着你有很多传播延迟。而且,由于单个进位可能会使整个结果不准确,因此必须等待相当长的一段时间才能得到所有进位值,然后,链中的所有其他全加器都会得到稳定

有很多方法可以解决这个瓶颈,但是没有一种方法可以像全加器链那样简单或资源廉价地实现。(最快的是用硅实现的查找表)


如果您想了解更多详细信息,您可能需要改为询问此问题

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

要回答您的最后一个问题,这取决于。有些架构只有1的移位(如z80),有些架构通过更大的常量和/或变量公开移位,但在内部实现为一组“1的移位”(如x86的旧实现),有些架构可以在单个周期内移位超过1,但前提是移位量为常量,有一些体系结构(例如x86的现代实现)使用一个变量,并且可以在单个周期内通过一个变量进行移位,还有更多的可能性

桶形移位器的电路深度在它能做的最大移位中是对数的,这不一定是区域的宽度