请教大家一个计算机组成原理的问题

2023-04-17 15:48:27 +08:00
 OrdinaryMan

当初大学计组这里就没想明白,最近重学机组还是在这里碰壁,故来 v 站请教各位 IT 同志: 既然现代计算机都是按字节编制,也就是每个地址对应一个字节大小的存储单元,也就是说按字节编制存储字长就是 8 位,那为什么存储字长还可以是 32 位,64 位? 我知道这句话肯定有问题,具体是哪里除了问题呢?

7571 次点击
所在节点    程序员
76 条回复
0littleboy
2023-04-17 17:48:44 +08:00
字节和字长是两个不同的概念,寻址位宽和数据位宽又是两种概念

https://www.cnblogs.com/komorebi-514/p/16174395.html
shendaowu
2023-04-17 21:01:43 +08:00
看了 OP 的帖子回复我也没怎么理解 OP 到底是怎么想的。希望 OP 能多说说你是怎么想的。否则有种无从下手的感觉。我尝试答一下吧,可能跟 OP 想要的答案有区别。

从地址为 0 的地址取一个 64 位的数据就是将内存地址为 0 到 7 的八个内存单元的数据整体传输到 CPU 。
从地址为 0 的地址取一个 32 位的数据就是将内存地址为 0 到 3 的四个内存单元的数据整体传输到 CPU 。
从地址为 1 的地址取一个 32 位的数据就是将内存地址为 1 到 4 的四个内存单元的数据整体传输到 CPU 。
从上面的例子来看,第一个和第三个的地址不同,但是存储单元有重合。不知道算不算你说的多个地址指代的是一个存储单元。

数据传输到 CPU 后最终会存入寄存器。寄存器是有多种位数的,另外一个更长的寄存器好像还可以拆成多个短的寄存器用。存入寄存器的数据经过运算后可以再存回内存。过程与从内存取类似。

总之 8 位是一个内存单元的位数,32 位或者 64 位一般是 CPU 一次能运算的位数。一般 CPU 一次只能读取指定位数的数据到寄存器,具体多少我没去查。如果一次存取不行可能会多次。考虑到类似 SIMD 的特性可能还会有变化。

或者说 8 位是内存能一次存取的最小单元,也是寻址的最小单元。某些单片机上好像能一次存取一位,但是地址好像不是以一位为一个单元的。而 SSD 一次只能存取很大的一块。我搜了一下好像是好几百 KB 。不知道把不同的存储器对比一下能不能让 OP 更好理解一点。

考虑到缓存之类的东西上面说的跟实际发生的可能有一定区别,但是应该符合真空中的球形电脑。可能有错误地地方,毕竟我只是个野生程序员。

如果还是不懂建议看看《编码》( https://book.douban.com/subject/4822685/ )吧。
duke807
2023-04-17 22:05:35 +08:00
主要和 CPU 内部总线有关

内部总线又和 CPU 架构有关

CPU 所使用的指令集,如果默认支持的是 32 位操作,譬如 ADD 加法指令(操作的寄存器也是 32 位),那么 CPU 就是 32 位

类似的,现在还在市面上的 CPU 可以是 8 位 16 位 32 位 64 位

既然 32 位 CPU 一个指令可以操作 32 位,那么内存默认也就按照 32 位加载数据了,这样最方便
(如果加载的数据不是 32 位对齐的,低端 CPU 会直接异常出错,譬如 cortex-m0+,高端一点的 cpu 则会分两次加载,叫做支持非对齐访问)

如果想看细节,可以看我这个 CPU 外设的接口:

https://github.com/dukelec/cdbus#interface

这个是 8 位的接口,数据块大小是 256 字节,所以 地址线是 [4:0] 共 5 根线,数据则是 8 根线,对应一个字节

而这个外设也有 32 位的接口的版本:

https://github.com/dukelec/cdbus/tree/32-bit#interface

32 位的版本,可以直接访问多个连续的数据块,所以地址线没变少,要留意的是 _mm_byteenable 信号,当需要读写 32 位其中的部分的时候,通过 byteenable 选中要操作的字节,至于是否支持非对齐访问,那是上面总线的事
OrdinaryMan
2023-04-17 22:16:11 +08:00
@shendaowu 完全按照书本里说的:地址总线的条数决定寻址空间大小,每个地址对应一个存储单元;存储空间的位数决定了数据总线的条数。这样理解有什么问题吗?
OrdinaryMan
2023-04-17 22:18:27 +08:00
@duke807 完全按照书本里说的:地址总线的条数决定寻址空间大小,每个地址对应一个存储单元;存储单元的位数决定了数据总线的条数。这样理解有什么问题吗?
Helsing
2023-04-17 22:23:50 +08:00
这里的 8 位、32 位、64 位其实对应的是物理上的地址线引脚的个数,每根引脚对应操作 1 bit ,也就是根据硬件参数的不同,CPU 每次能够读取的存储数据可以是 8 bit 、32 bit 或者 64 bit

从 8 位到 64 位,其实是为了提高 CPU 的存取效率

虽然 CPU 的存取效率提高了,但是数据存储格式其实是不变,还是 1 比特 1 比特地存储在存储介质中的
liveoppo
2023-04-17 22:26:33 +08:00
我猜着楼主的意思回答一下。

虽然内存是按 8bit 的字节来编址的,但是先进的 32bit 的 CPU 一次可以操作的可能是 4 个字节,也即 32bit 位的。举例,仅仅使用地址 0xAAAA0000 ,但使用 32bit 宽度,你可以同时操作内存地址为 0xAAAA0000 、0xAAAA0001 、0xAAAA0002 、0xAAAA0003 对应的 4 个字节。

楼主又问:意思是现代计算机虽然是按字节编址,但是实际上存储单元大小是字节整数倍。所以多个地址可能指代的是一个存储单元吗

回答:比如地址 0xAAAA0000 、0xAAAA0001 、0xAAAA0002 、0xAAAA0003 构成一个存储单元,如果按 32bit 存取,只能使用 0xAAAA0000 这个地址,如果按 8bit 字节存储,则分别使用各个字节的地址。
duke807
2023-04-17 22:36:19 +08:00
@OrdinaryMan #25 没问题
OrdinaryMan
2023-04-17 22:40:23 +08:00
@duke807 如果没问题,那么按照字节寻址的意思就是由地址总线产生的每个地址对应的存储单元就是一个字节,那这样数据总线条数不就固定死了是 8 位么?但是现实不是这样的啊
kaedeair
2023-04-17 23:05:32 +08:00
@OrdinaryMan 29# CPU 不仅可以按字寻址还可以按字节寻址,你说的是按字节寻址的情况。CPU 按字寻址和数据总线位宽有关,即多少多少位的 CPU 是指这个。一般现在的 64 位 CPU 地址总线是一般 40 位,数据总线是 64 位。推荐学习一下数电里面字扩展和位扩展那一节
WytheHuang
2023-04-17 23:08:50 +08:00
看看 b 站这个视频前十个后再来看书,应该好懂一点
[Crash Course Computer Science]( https://www.bilibili.com/video/BV1EW411u7)
WytheHuang
2023-04-17 23:09:56 +08:00
复制错了, 少了 th 。正确地址:
https://www.bilibili.com/video/BV1EW411u7th
kaedeair
2023-04-17 23:13:29 +08:00
@Helsing 26# CPU 的位数是指数据总线位宽,而不是地址总线位宽
lemonleo
2023-04-17 23:20:22 +08:00
感觉令你疑惑的可能是“字节”和“字”,它们分别是 byte 和 word ,这俩不是一个概念。
opengps
2023-04-17 23:29:13 +08:00
举个例子你就明白了,我最近经历的:
我写了个多线程程序,编译成 32 位程序时候只能用满 32 个 vcpu 。但我改成 64 位编译就可以直接使用当前的 40 个 vcpu 。
也就是说操作系统的多少位与 cpu 使用有直接关系。延伸下看看内存也是
LiSrRbE2Mac
2023-04-17 23:31:39 +08:00
纠正一下前面的发言
实际上处理器的位数应该由通用处理器位数决定而不是地址总线的位数

比较经典的例子就是 8086 处理器,地址总线从 AD0-AD15,A16-A19 共 20 根地址线
但实际上 8086 属于典型的 16 位处理器

更严格来说,以数据总线位宽定义也不太准确,某些 dsp 或者 riscv 处理器中允许一次读操作从 soc 的外设中读取多个值并在一个写回(wb)操作中写回寄存器堆

但大多数情况可以将数字总线的位数等同于处理器的位数
kangyue9999
2023-04-17 23:32:21 +08:00
比如你买房子,最小的叫一户室,然后之后还有一室一厅,一室两厅等等

最基础的一个单元是 8 字节,然后根据架构(基本上是跟 ISA 绑定的)不一样一个字就可能有 8 位,16 位,32 位这样 https://zh.wikipedia.org/wiki/%E5%AD%97_(%E8%AE%A1%E7%AE%97%E6%9C%BA)

也就相当于有的小区标准是一室一厅,有的小区标准户型是两室一厅

不过现在在 x86 计算体系下面 一个字是 16 位 双字是 32 位

arm 体系则是一个字 32 位。
kangyue9999
2023-04-17 23:34:27 +08:00
@kangyue9999 纠正一下,传统的 8086 是 16 位一个字,386 以后就是 32 位一个字了 armv64 以后已经是 64 位一个字了
yuanix
2023-04-17 23:42:10 +08:00
数据总线如果是 32 位,就能一次传输 32 位的数据,如果是 64 位就能一次传输 64 位数据。
duke807
2023-04-17 23:42:44 +08:00
@OrdinaryMan

如果 CPU 是 8 位的,那么数据通道固定是 8 根线没错

但如果 CPU 是 32 位的,那么数据通道固定是 32 根线,也就是同时可读写 4 个字节
如果您只想读其中一个字节,我上面说了,要通过类似 byteenable 这样的 mask 信号,自己选择要读写哪个字节
此时,32 根线(或者说 4 个字节),只有其中选中的字节会参与读写,没选中的字节(或位)被忽略掉而已

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/933184

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX