例子

例子

当今广泛使用的大多数处理器/CPU 的位数都是 2 的幂(通常为 32 和 64,但也有 16、8 和 4 位)。

尽管位数的含义并不一致(有人说它是字大小、寄存器的大小、指令宽度、数据或地址总线宽度等),但这些几乎总是 2 的幂。

我知道有一些例外,例如 Intel 8086 有一个 20 位地址总线,但正如我所说通常2 的幂。

为什么会发生这种情况,有哪些例外,以及为什么?

答案1

8 位字节

这在很大程度上源于 8 位字节的采用。这种字节在 1964 年 IBM 360 系列计算机推出后开始流行。在当年的一期 IBM 技术期刊中,对这一选择进行了解释:

字符大小,6 比 4/8:在字符大小方面,根本问题是十进制数字需要 4 位,而字母数字字符需要 6 位。考虑了三种明显的替代方案 - 全部 6 位,数字数据浪费 2 位;数字 4 位,字母数字 8 位,字母数字浪费 2 位;数字 4 位,字母数字 6 位,这需要采用 12 位模块作为最小可寻址元素。还简要检查了 7 位字符,它包含十进制数字对的二进制重新编码。

4/6 方法被拒绝,因为(a)希望它具有处理字符流和寻址单个字符的多功能性和能力,即使在未使用十进制算术的模型中也是如此,(b)将字母字符限制为 6 位似乎是目光短浅的,并且(c)这种方法的工程复杂性可能比字符中浪费的位还要昂贵。

IBM 702-7080 和 1401-7010 系列以及其他制造商的系统中使用的直接 6 位方法具有以下优点:使用熟悉、现有的 I/O 设备、规范字段结构简单,并且与 48 位浮点字和 24 位指令字段可比性。

IBM 650-7074 系列和其他产品中使用的 4/8 方法具有更高的编码效率、字母集中的备用位(允许字母集增长)以及与 32/64 位浮点字和 16 位指令字段的可比性。这些因素中最重要的是编码效率,这是因为业务记录中数字数据的使用频率是字母数字的两倍多。对于给定的硬件投资,这种效率意味着可以更好地利用核心存储、更快的磁带和容量更大的磁盘。

总体而言,按照当时的标准,8 位字节允许相当大的字符集,并且每个字节允许两个 BCD 数字。

转向字节寻址

最早的计算机设计优先考虑的是尽可能快地处理数字。数字通常存储在一个机器字中,所需的数值范围决定了字的大小。指令通常是一个字,并且每个指令通常都有一个地址。指令中地址字段的大小决定了内存大小。IBM 704/709就是一个例子;它最多有 4096 个 36 位字,每个字有 6 个字符,每个字符 6 位。地址为 12 位。

随着计算机的使用范围不断扩大,处理文本数据变得越来越重要。在字寻址的机器中执行此操作充其量也只是麻烦而已。字节寻址的机器允许您轻松访问单个字符,但需要更大的地址字段。同时,磁芯存储器允许构建很多比真空管、静电存储器或延迟线更大的存储器。

这些发展从本质上迫使计算机拥有更大的地址空间,并结束了每条指令都有一个地址的做法。

更大的数据项

显然,每个数据项使用整数字节数会使事情变得更简单。这种级别的简单性非常值得,因为在有限的电子部件预算(早期是电子管,后来是晶体管)内让计算机尽可能快地运行始终很重要。因此,两个字节(16 位)成为明显的大小。

对于较大的尺寸,电子设计中会出现两个因素:

数数

执行指令通常需要对数据项的字节(或位)进行计数。使用 2 的幂可以使这些计数器的电子元件更简单。要对 4 个字节进行计数,您需要一个 2 位计数器,它可以保存从 0 到 3 的值。对 3 个字节进行计数仍然需要一个 2 位计数器,但其中一个值是无意义的,必须在硬件中作为特殊情况处理。

通过串行线路发送数据需要对每一项的位进行计数,这是 8 位字节的另一个好处。3 位计数器可以处理它们,无需任何特殊情况。

IBM 360 选择了 32 位地址(尽管在其最初十年只允许使用 24 位内存地址),并且一旦建立,使用 8 位字节和 32 位地址与 IBM 竞争要比你想做一些不同的事情容易得多。

内存提取和数据对齐

如果数据项是“对齐的”,则从内存中获取数据会更简单。这意味着它们的地址是其大小的倍数。因此,对于字节寻址的机器(如 IBM 360),单个字节可以位于任何地址。如果双字节(16 位)项位于偶数地址,则它是“对齐的”。如果四字节(32 位)项的地址是 4 的倍数,则它是对齐的。

20 世纪 60 年代到 90 年代的许多计算机设计都具有可以在一次操作中获取 4 个字节的内存,从 4 的倍数的地址开始。如果您的数据项是对齐的,那么您保证能够获取一次操作中的任何两字节或四字节项。单身的从内存中读取。如果它们未对齐,有时需要两次提取。这需要内存访问系统更加复杂,以识别操作未对齐并生成额外的提取。这种复杂性和额外的提取会减慢速度。

大于 4 个字节的项目将需要两次提取,但如果您的较大项目是 8 个字节,并且与 8 字节边界对齐,那么生活就更简单了。那么您总是需要恰好两次提取。如果您有未对齐的 8 字节项目,那么您需要获取。

在现代快速系统中,读取的总是完整的缓存行,通常为 32 或 64 字节。这些缓存行始终是对齐的,并且适合这些缓存行的对齐数据项始终是完整到达的。

相当多的计算机设计将未对齐的获取视为程序错误,并终止执行该错误的程序。基于 x86 的系统不会这样做,但必须付出复杂性的代价。它们确实运行快点具有对齐的数据,因此即使它不是强制性的,也通常会使用。

24 位系统

我使用过 24 位系统,即 ICL 1900 主机。它使用 6 位字节,每个 24 位字有 4 个字节。这些 6 位字节将其限制为大写文本,而 24 位指针将其限制为 16MB RAM,这按今天的标准来说很小。

更现代的 24 位系统采用 8 位字节,但仍然受限于 16MB 的易于寻址的内存,并且会付出计数器具有不必要状态的成本,以及内存项要么未对齐,要么为每个 24 位整数浪费一个字节的内存。32 位系统将更强大,并且以当今的技术可以非常便宜地构建。

历史教训

曾经有两款颇具影响力的计算机系统拥有 32 位整数和指针,但使用 24 位寻址。它们是 Motorola 68000 和 IBM 360。在这两种情况下,都只使用地址的最低 24 位,但存储在内存中的地址占用 32 位。

由于这些系统的 RAM 限制为 16MB,程序员将其他数据存储在备用的 8 位中。当 16MB RAM 显然不够用,并且设计扩展到 32 位寻址时,如果将存储在备用位中的数据视为地址的一部分,那么这些数据就会成为一个严重的问题。

在 68000 系列上,现有程序必须进行更改才能停止使用这些不再多余的位。这在 20 世纪 80 年代末的 Macintosh 软件行业中最为明显,当时更新了 68020 兼容性,但同样的事情也发生在 Amiga 上,大概还有其他基于 68000 的系统。

在 IBM 360 的后续产品上,24 位地址程序仍可运行,使用更大地址的程序亦可运行。但 32 个地址位中只有 31 个可用;牺牲了一个地址位,以便让硬件区分两种代码。

后 32 位设计

所有设计过寻址大于 32 位的通用架构的人都知道 360 和 68000,也知道 24 位寻址带来了多大的麻烦。没有人认真地尝试设计像实模式 x86 这样的分段架构来超越 32 位寻址。每个人都使用平面地址空间。对于地址大小,只有少数几个模糊合理的选择。

  • 40 位寻址很复杂。电子设备在通过位和字节计数时有未使用的值。如果内存提取是 32 位,则 40 位指针始终需要两次提取;如果内存提取是 40 位,则某些 16 位和 32 位提取需要两次提取操作,而某些 64 位提取需要三次。您可以通过将 32 位数量扩大到 40 位,将 64 位数量扩大到 80 位来减少这一点,但这不是一个好主意 - 见下文。

  • 40 位寻址也不会持续太久。它只允许寻址 1024GB,而截至 2023 年,这对某些市场来说已经是一个问题。将 40 位寻址扩展到更大的地址空间将导致另一轮中断,因为软件已更新以利用它,并且可能会破坏对 40 位的向后兼容性。它还为您提供其他如果选择 40 位和 80 位选项,则对齐复杂度会增加一轮。

  • 48 位或 56 位寻址与 40 位寻址一样复杂,尽管它们可能会持续更长时间,但是当您走到这一步时,您最好一路走下去。

  • 64 位比 40、48 或 56 位更易于构建。它的使用寿命更长。其寄存器大小与标准浮点数据大小相匹配。这似乎合乎逻辑。

第一个发布的通用后 32 位微处理器是 1991 年发布的 MIPS R4000、同样在 1991 年发布的 Kendal Square Research KSR-1 以及 1992 年发布的 DEC Alpha。

  1. 我对 MIPS 项目了解不多,但它是 32 位 R2000 和 R3000 微处理器的 64 位扩展。SGI 在 1991-92 年陷入财务困境时收购了 MIPS,以确保其工作站产品的处理器供应。

  2. KSR-1 是一台超级计算机,至少有 8 个他们自己设计的 64 位微处理器。但它并没有成功。

  3. DEC 项目的效果最显著,因为 DEC 当时是一家大型计算机公司。该项目始于 1988 年,最初旨在长期保持 32 位 VAX 架构的相关性。设计师很快意识到这是不切实际的,于是设计了一个新架构,预计至少可以使用 25 年。因此,他们采用了 64 位寻址,以确保不会耗尽地址空间。

发布一款非 64 位的 Alpha 或 MIPS 竞争对手显然会面临营销问题,人们会问“为什么不是 64 位?”。因此 64 位成为了共识。更新的 RISC-V 架构为 128 位寻址提供了一些支持,尽管这还没有设计出来。

一个重要的细节:目前没有 64 位处理器可以真正连接 64 位内存。它们都没有足够的地址线。这没关系。将来的实现可以赋予更多的地址线。必须阻止程序员使用“备用”地址位,但这样做是可行的,操作系统可以设计为拒绝这种使用。

64 位 ARMv9-A 具有可选功能来提高安全性,这些功能使用了一些“备用”高位,但它们选修的,旨在用于目前不需要 PB 级和 EB 级内存的移动设备。

答案2

具有 2ⁿ 位寄存器,允许使用整数位数来寻址寄存器中的位:

寻址 8 位寄存器中的一位需要 3 位。寻址 16 位寄存器中的一位需要 4 位。但是,寻址 12 位寄存器中的一位需要 3.58… 位。您必须将其四舍五入为 4,从而浪费 ≈0.4 位。

例子

  • 立即移位:移位距离存储在指令中。
  • 立即读位:从寄存器中读取一位,位号在指令中指定。
  • 从一个大的内存字段读取或写入一个位:掩码(按位与)获取地址的高位并使用这些位作为字节地址,掩码(按位与)获取地址的低位并使用这些位作为位偏移量。

我们并不总是使用寄存器来指定位。我们经常使用立即寻址(地址在指令中)。即使 arm 也这样做,但它没有立即寻址(在字节级别)。当我们在寄存器中有地址时,我们通常要处理的是超过 32 位的数据,因此必须屏蔽地址以获取字节数和位数。这只有在 2 的幂下才有效。

答案3

最常见的原因是计算机使用二进制系统,其中一位可以是零或一。如果计算机使用三进制值表示位,那么所有值都是 3 的幂。

关于 RAM/内存:

地址总线(用于选择地址)中的 N 位可以寻址2^N字节。每当地址位数增加到 时N+1,可寻址空间就会自动增加 2 倍。

制造商在设计中包含内存芯片时自然会使用最大地址容量,因此内存大小自然是 2 的幂。

关于寄存器大小:

同样的道理也适用,因为硬件内部可以使用其数字来寻址寄存器中的一位,这又是二进制表示的。

(所有这些只是一种假设,也是对实际情况的极大简化。我相信电气工程师能够证明为什么基于二进制逻辑的电路自然会使用幂二。正如英特尔 8086 所显示的那样,其他数字也是可能的,但制造成本可能更高。)

答案4

我认为这更多的是一种惯例,而不是技术问题。

维基百科关于计算机体系结构中字长选择的页面有一张漂亮的桌子很多旧计算机架构的字节/字大小不是 2 的幂。该页面的右上角还有一个框,其中有指向许多非常规字大小(例如 12、18、24 以及 31、36、45 (!) 等)的单独页面的链接。

字节/字大小具有重大影响的一个领域是编译器;即,您的 C 编译器需要知道寻址寄存器中有多少位可用(即 16/24/32/64 位),并且许多方面都源于此(即,整数数组在内存中的布局方式以及编译器如何生成访问该数组的代码)。

当然,为一个字长构建的代码通常也与为其他字长构建的代码不兼容,即使所讨论的 CPU 对其汇编语言使用完全相同的编码。

另外,如果你的数据存储是二进制的——在过去,将一页内存转储到一个文件中,然后按“原样”读回来并不是什么新鲜事——如果两台机器使用不同的字长,这种方法就会完全失效(即使其他方面,比如字节序, 是相同的)。

所有这些都导致行业趋向于越来越小的字长,就像多年来许多其他技术方面趋向一样。正如用户 alt-ctrl-delor 在他的回答中提到的那样,这里的一个(可能是次要的)方面可能是,如果您的 CPU 中有一些整数,甚至可能仅在内部/硬件中,您希望在其中存储位在寄存器中的位置(即,从 0 到寄存器的字长范围内的动态值),那么使用 2 的幂的寄存器宽度可以避免浪费和一些错误状态(即,寻址超过非 2 的幂字长的位)。

相关内容