Law*_*ceC 35
32 位 CPU 的含义之一是其寄存器为 32 位宽。这并不意味着它不能处理 64 位数字,只是它必须先处理较低的 32 位一半,然后再处理较高的 32 位一半。(这就是 CPU 具有进位标志的原因。)它比 CPU 仅将值加载到更宽的 64 位寄存器中要慢,但仍然可能。
因此,系统的“位数”不一定会限制程序可以处理的数字的大小,因为您总是可以将不适合 CPU 寄存器的操作分解为多个操作。因此它使操作变慢,消耗更多内存(如果您必须将内存用作“便签本”),并且更难以编程,但仍然可以进行操作。
但是,对于例如 Intel 32 位处理器和浮点,这些都无关紧要,因为 CPU 的浮点部分有自己的寄存器,并且它们的宽度为 80 位。(在 x86 的早期,浮点功能是一个单独的芯片,它从 80486DX 开始集成在 CPU 中。)
@Breakthrough 的回答激励我添加这个。
就浮点值存储在 FPU 寄存器中而言,它们的工作方式与二进制整数值非常不同。
浮点值的 80 位被分为尾数和指数(浮点数中也有“基数”,始终为 2)。尾数包含有效数字,指数确定这些有效数字的大小。所以没有“溢出”到另一个寄存器,如果你的数字太大而无法放入尾数,你的指数会增加并且你失去精度 - 即当你将它转换为整数时,你会失去右边的小数位 -这就是为什么它被称为浮点。
如果您的指数太大,则会出现浮点溢出,但由于指数和尾数被捆绑在一起,因此您无法轻松将其扩展到另一个寄存器。
我可能对其中一些内容不准确和错误,但我相信这就是它的要点。(这篇维基百科文章更简洁地说明了上述内容。)
这完全不同是可以的,因为 CPU 的整个“浮点”部分都在它自己的世界中 - 您使用特殊的 CPU 指令来访问它等等。此外,就问题而言,因为它是独立的,所以 FPU 的位数与本机 CPU 的位数并不紧密耦合。
Bre*_*ugh 13
32位、64位、128位都是指处理器的字长,可以认为是“基本数据类型”。通常,这是传入/传出系统 RAM 的位数,以及指针的宽度(尽管没有什么能阻止您使用软件访问比单个指针可以访问的更多的 RAM)。
假设一个恒定的时钟速度(以及架构中的其他一切都是恒定的),并假设内存读/写的速度相同(我们在这里假设 1 个时钟周期,但这与现实生活中的情况相去甚远),你可以在 64 位机器上的单个时钟周期内添加两个 64 位数字(如果计算从 RAM 中获取数字,则为三个):
ADDA [NUM1], [NUM2]
STAA [RESULT]
Run Code Online (Sandbox Code Playgroud)
我们也可以在 32 位机器上做同样的计算……但是,在 32 位机器上,我们需要用软件来做,因为必须先添加低 32 位,补偿溢出,然后添加高 64 位:
ADDA [NUM1_LOWER], [NUM2_LOWER]
STAA [RESULT_LOWER]
CLRA ; I'm assuming the condition flags are not modified by this.
BRNO CMPS ; Branch to CMPS if there was no overflow.
ADDA #1 ; If there was overflow, compensate the value of A.
CMPS ADDA [NUM1_UPPER], [NUM2_UPPER]
STAA [RESULT_UPPER]
Run Code Online (Sandbox Code Playgroud)
通过我编写的汇编语法,您可以很容易地看到,在较低字长的机器上,更高精度的运算是如何花费指数级更长的时间的。这是 64 位和 128 位处理器的真正关键:它们允许我们在单个操作中处理更多的位。一些机器包括使用进位添加其他数量的指令(例如ADC在 x86 上),但上面的示例考虑了任意精度值。
现在,将这个问题扩展到这个问题,很容易看出我们如何添加大于可用寄存器的数字 - 我们只需将问题分解为寄存器大小的块,然后从那里开始工作。尽管正如@MatteoItalia所提到的,x87 FPU 堆栈原生支持 80 位数量,但在缺乏这种支持的系统中(或完全缺乏浮点单元的处理器!),等效的计算/操作必须在软件中执行。
因此,对于 80 位数字,在添加每个 32 位段之后,还要检查是否溢出到第 81 位,并可选择将高阶位清零。这些检查/归零是针对某些 x86 和 x86-64 指令自动执行的,其中指定了源和目标操作数的大小(尽管这些仅以 2 的幂从 1 个字节开始指定)。
当然,对于浮点数,不能简单地执行二进制加法,因为尾数和有效数字以偏移形式打包在一起。在 x86 处理器上的 ALU 中,有一个硬件电路可以为 IEEE 32 位和 64 位浮点数执行此操作;然而,即使没有浮点单元 (FPU),也可以在软件中执行相同的计算(例如,通过使用GNU 科学库,在架构上编译时使用 FPU,回退到软件算法如果没有可用的浮点硬件(例如对于缺少 FPU 的嵌入式微控制器))。
给定足够的内存,人们还可以对任意(或“无限”——在现实范围内)精度的数量进行计算,在需要更高的精度时使用更多的内存。GNU Multiple Precision library 中存在这种实现的一种实现,允许对整数、有理数和浮点运算进行无限精度(当然,直到您的 RAM 已满)。
系统的内存架构可能只允许您一次移动 32 位 - 但这并不能阻止它使用更大的数字。
想想乘法。您可能知道高达 10x10 的乘法表,但在一张纸上执行 123x321 可能没有问题:您只需将其分解为许多小问题,将单个数字相乘,并处理进位等。
处理器可以做同样的事情。在“过去”,您有 8 位处理器可以进行浮点数学运算。但他们太慢了。
| 归档时间: |
|
| 查看次数: |
6624 次 |
| 最近记录: |