在C++中,你可以使用一个通常为4个字节的int
。一个long long
整数通常是8个字节。如果CPU是32位的,那么不会限制32位数字吗?如果它不支持64位,我怎么能使用long long
整数? ALU是否可以添加更大的整数或其他内容?
大多数处理器都包括进位标志位和溢出标志位,以支持对多字节整数的操作。进位标志位用于无符号运算,而溢出标志位用于有符号运算。
例如,在x86上,您可以像这样添加两个无符号64位数字(我们假设它们在EDX:EAX和EBX:ECX中):
add eax, ecx ; this does an add, ignoring the carry flag
adc edx, ebx ; this adds the carry flag along with the numbers
; sum in edx:eax
在像C++这样的高级语言中也有可能实现这种东西,但它们对此的支持要少得多,因此代码通常比用汇编语言编写时慢得多。
大多数操作基本上是按顺序进行的。当您以二进制级别进行加法运算时,您需要取两个输入位并产生一个结果位和一个进位位。然后在添加下一个最低有效位时,将使用进位位作为输入,并依此类推(称为“涟漪加法器”,因为加法在整个字中“涟漪”传递)。
有更复杂的方法可以执行加法,可以减少在特定加法不产生依赖性时一个比特与另一个比特之间的依赖性,大多数当前的硬件都使用这些方法。
但在最坏的情况下,向已经是给定字大小支持的最大数字添加1
将导致从每个位到下一个位生成一个进位,一直到整个字为止。
这意味着(至少在某种程度上),CPU支持的字宽限制了它可以运行的最大时钟速度。如果有人非常想这样做,他们可以构建一个使用1024位操作数的CPU。如果他们这样做,他们就有两个选择:要么以较低的时钟速度运行它,要么需要多个时钟来添加单个操作数对。
另请注意,随着扩展这样的操作数,您需要更多的存储空间(例如更大的高速缓存)来存储尽可能多的操作数、更多的门来执行每个单独的操作等等。
因此,在相同的技术条件下,您可以拥有一个64位处理器,它以4 GHz的速度运行,并具有4兆字节的高速缓存,或者一个以大约250 MHz的速度运行并具有2兆字节高速缓存的1024位处理器。
如果您的工作中大部分都是在1024位(或更大)操作数上进行,则后者可能会获胜。但是,大多数人几乎从不对1024位操作数进行数学计算。实际上,64位数字对于大多数目的已经足够大了。因此,对更宽的操作数提供支持可能通常会导致大多数人在大多数情况下产生净损失。
基本上,通常的单指令加法被分成了两个(或三个)步骤:
1)使用通常的加法指令添加低位32位。请注意,此加法是否会生成“进位”位(即,如果结果实际上需要33位来表示)。
2)以相同的方式添加高位32位。如果从低位比特中有一个进位,则在此处设置进位输入比特(或者,在添加后将结果加一)。
您需要使用两个内存地址来存储这个数。这个数的一半被存储在内存中的一个地址,而另一半则存储在相邻的内存地址。