V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
OrdinaryMan
V2EX  ›  程序员

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

  •  
  •   OrdinaryMan ·
    YangFanJack · 2023-04-17 15:48:27 +08:00 · 8045 次点击
    这是一个创建于 587 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    第 1 条附言  ·  2023-04-18 09:47:54 +08:00
    感谢大家的回答,没想到一个小问题,大家这么热情。看了大家的回答,我目前的理解是:现代计算机虽然基本都是按字节寻址,内存空间的最小编址和寻址单位是字节存储单元。但是 CPU 指令在根据地址码取数的时候,不是根据一个字节地址就能取出一个字存储单元的内容(字存储单元包含整数倍个字节存储单元),而是需要根据字存储单元的首地址(这里有大端小端之分),每次取出一个字的数据送到数据总线传给 CPU 。我的误区应该在没有区分字节存储单元和字存储单元
    第 2 条附言  ·  2023-04-18 09:49:05 +08:00
    相关的是哈工大计组视频课上的内容,如图: https://sm.ms/image/gitTNylf7XBuVzF
    第 3 条附言  ·  2023-05-19 09:27:23 +08:00
    1. 指令的地址码表面指向的是一个字节存储单元,但实际上表示的是指令地址指向数据的首地址,至于这个数据有多大由指令的其他字位确定。exp:int a ,short b ,高级语言中的数据类型就决定了这个 size 。
    2. 根据一个地址码读出多个字节,最后根据大端小端拼接成完整数据
    3. 根据一个地址码读出的数据 size 大小是有限制的,这个限制就是 MDR 位宽,也就是存储字长
    76 条回复    2023-05-06 09:27:20 +08:00
    raymanr
        1
    raymanr  
       2023-04-17 16:04:24 +08:00   ❤️ 1
    在计算机中,存储单元的大小是按位( bit )衡量的,换句话说,一个存储单元可以存储的二进制位数决定了它的大小。虽然现代计算机的存储单元是按字节( byte )衡量的,即每个存储单元对应 8 位二进制数,但是计算机的指令集可以使用不同的位数来操作数据和地址。

    因此,存储字长( word size )是指 CPU 处理数据和地址时使用的二进制位数。虽然常见的存储字长包括 8 位、16 位、32 位和 64 位等,但是它不一定与存储单元的大小相同。事实上,存储字长需要考虑多个方面的因素,例如 CPU 架构、操作系统、应用程序等。存储字长的大小可以影响计算机的性能和可用内存空间等。

    因此,尽管现代计算机的存储单元是按字节编制的,但存储字长可以是不同的位数,这取决于具体的计算机体系结构。

    FROM CHATGPT.
    magicfield
        2
    magicfield  
       2023-04-17 16:23:33 +08:00   ❤️ 1
    位就是 01 一个存储单位,字节就 8 位的存储长度
    ASCII 码就是典型一个字节存储的
    GBK 是两个字节存储的,你也可以认为是 16 位存储长度
    UTF-8 是 1~4 字节就可以是 8~32 位

    不用特别在意单位,反正都是能换算的

    至于电脑的 32 位或 64 位指的是 CPU 一次能处理的位数
    elmagnificogg
        3
    elmagnificogg  
       2023-04-17 16:24:59 +08:00
    最初确实是 8 位,但是这样的 cpu 效率太低了,一次才能处理一字节所对应的命令或者数据,完全不够用

    为了提升效率就有了 16 位、32 位到现在好不容易普及的 64 位

    现在应该是没有什么字节编制这么一说,基本上大部分存储设备目前都是有对齐要求的,对齐的大部分也都远超 8 位,很多 32 位对齐,128 位对齐,4k 对齐,这个和实际的存储芯片设计的存储结构有关系和缓存加速读取也有关系
    NaiveSimpleYoung
        4
    NaiveSimpleYoung  
       2023-04-17 16:27:21 +08:00 via Android   ❤️ 5
    @raymanr 建议把 「 FROM CHAT GPT 」放在开头
    hxm0070
        5
    hxm0070  
       2023-04-17 16:28:35 +08:00   ❤️ 2
    CPU 是 8 位的物理意义上指的是地址线引脚有 8 个,但是最早期的时候什么 4 位的 5 位的 7 位的乱七八糟的都有。
    后来 Byte 定为 8 其实有一个过程,4/5/6/7 都有人用过,最终要包含所有常用的英文字符一共有 128 个(现在的 ASCII ),正好 7 位,然后可能还有别的一些因素(存储芯片成本降低了一些可以浪费 1 位、8 又是 2 的次幂方便计算机处理、与早期较流行的 6bit 一定程度可以兼容等等等等大家都这么猜测),1964 年的 IBM System/360 就用了 8 位,IBM 兼容机就这么沿用下来了。
    后来位数成倍增加最主要的原因是 CPU 对内存的直接寻址空间不够了(因为地址线引脚就这么多),比如前几年升级 64 位的时候都在说的 32 位电脑理论上的 RAM 最大 4G 左右就是这个寻址空间了。。
    nyxsonsleep
        6
    nyxsonsleep  
       2023-04-17 16:30:33 +08:00
    拿单片机的数据引脚、gpio 来类比来说就是有的只有 8pin ,有的 16pin 。但在正确设计的情况下,并不影响读取、交换数据。
    brader
        7
    brader  
       2023-04-17 16:44:11 +08:00
    说下我的认知(非专业,仅供参考):
    当下主流的 cpu 架构来说,我认为 cpu 位宽和外存储器的存储字长没有很强的强关联关系。
    现在的计算机结构,cpu 更多的是和 CPU 寄存器,总线,内存 这些打交道,cpu 的位宽会决定这些配件的位宽,外存储器的数据是加载到内存后,才给 cpu 使用的。
    009694
        8
    009694  
       2023-04-17 16:47:42 +08:00 via iPhone   ❤️ 1
    @raymanr gpt3.5 的回答就不要放上来了,要放也得放 4 的 3.5 的免费接口免费站已经满天飞了 不至于劳烦各位代问
    tusj
        9
    tusj  
       2023-04-17 16:50:00 +08:00
    大概就是米饭一粒一粒的吃太慢了,就一勺一地吃呗
    DeWjjj
        10
    DeWjjj  
       2023-04-17 16:50:16 +08:00
    首先我们知道 CPU 有一个快速缓存对吧,那个的大小就是严格对齐 64 位 32 位的。
    只是在计算机最初,他们是 64 和 32 而已,现在你会发现的就是即是不是 x86 的一样可以通用,是因为现在快速缓存区已经远超当年设定的值了。
    OrdinaryMan
        11
    OrdinaryMan  
    OP
       2023-04-17 16:53:57 +08:00 via Android
    @brader 我的问题里存储单元的存储器就是指的内存
    OrdinaryMan
        12
    OrdinaryMan  
    OP
       2023-04-17 16:56:37 +08:00 via Android
    @hxm0070 意思是现代计算机虽然是按字节编址,此时实际上存储单元大小也可能是字节整数倍。所以多个地址可能指代的是一个存储单元吗
    YCCD
        13
    YCCD  
       2023-04-17 16:57:05 +08:00 via iPhone
    每个地址对应一个存储单元,一个存储单元 8bit ( 8 位)
    4 个存储单元就 32bit ( 32 位),就一个 int 大小
    8 个存储单元就 64bit ( 64 位),一个 double 的大小
    OrdinaryMan
        14
    OrdinaryMan  
    OP
       2023-04-17 16:59:02 +08:00 via Android
    @YCCD 意思是现代计算机虽然是按字节编址,但是实际上存储单元大小是字节整数倍。所以多个地址可能指代的是一个存储单元吗
    YCCD
        15
    YCCD  
       2023-04-17 17:01:04 +08:00 via iPhone
    0x8000 到 0x8004 代表四个存储单元,代表一个 int ( 32 位)
    @OrdinaryMan
    kaedeair
        16
    kaedeair  
       2023-04-17 17:06:17 +08:00   ❤️ 1
    CPU 寻址位宽和数据位宽不是一个概念
    Pil0tXia
        17
    Pil0tXia  
       2023-04-17 17:29:47 +08:00   ❤️ 3
    看来楼上的还了不少给学校老师了😎
    #16 正解。CPU 的那个“位”是内存地址的位数,比如 32 位的 CPU 只能管理 4GB 的内存; int 、double 的“位”是寻址找到内存地址后对象的大小。
    feather12315
        18
    feather12315  
       2023-04-17 17:32:02 +08:00 via Android
    16 楼正解,属于叫 cacheline
    raymanr
        19
    raymanr  
       2023-04-17 17:32:44 +08:00
    @OrdinaryMan 简单的模型就是 CPU 有一个寄存器, 存放了 32 位或者 64 位的偏移量去定位内存的位置, 内存里面的东西是 8 位, 但是这个 8 位数据所在的地址是 32/64 位的.
    raymanr
        20
    raymanr  
       2023-04-17 17:35:55 +08:00
    推荐楼主看一下 <操作系统导论> 这本书, 里面对于 CPU 和内存, 磁盘机制有相应描述. 本来我觉得我 1 楼复制粘贴的回答已经说明白了
    0littleboy
        21
    0littleboy  
       2023-04-17 17:48:44 +08:00
    字节和字长是两个不同的概念,寻址位宽和数据位宽又是两种概念

    https://www.cnblogs.com/komorebi-514/p/16174395.html
    shendaowu
        22
    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
        23
    duke807  
       2023-04-17 22:05:35 +08:00 via Android
    主要和 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
        24
    OrdinaryMan  
    OP
       2023-04-17 22:16:11 +08:00
    @shendaowu 完全按照书本里说的:地址总线的条数决定寻址空间大小,每个地址对应一个存储单元;存储空间的位数决定了数据总线的条数。这样理解有什么问题吗?
    OrdinaryMan
        25
    OrdinaryMan  
    OP
       2023-04-17 22:18:27 +08:00
    @duke807 完全按照书本里说的:地址总线的条数决定寻址空间大小,每个地址对应一个存储单元;存储单元的位数决定了数据总线的条数。这样理解有什么问题吗?
    Helsing
        26
    Helsing  
       2023-04-17 22:23:50 +08:00 via iPhone
    这里的 8 位、32 位、64 位其实对应的是物理上的地址线引脚的个数,每根引脚对应操作 1 bit ,也就是根据硬件参数的不同,CPU 每次能够读取的存储数据可以是 8 bit 、32 bit 或者 64 bit

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

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

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

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

    但大多数情况可以将数字总线的位数等同于处理器的位数
    kangyue9999
        37
    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
        38
    kangyue9999  
       2023-04-17 23:34:27 +08:00
    @kangyue9999 纠正一下,传统的 8086 是 16 位一个字,386 以后就是 32 位一个字了 armv64 以后已经是 64 位一个字了
    yuanix
        39
    yuanix  
       2023-04-17 23:42:10 +08:00 via Android
    数据总线如果是 32 位,就能一次传输 32 位的数据,如果是 64 位就能一次传输 64 位数据。
    duke807
        40
    duke807  
       2023-04-17 23:42:44 +08:00
    @OrdinaryMan

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

    但如果 CPU 是 32 位的,那么数据通道固定是 32 根线,也就是同时可读写 4 个字节
    如果您只想读其中一个字节,我上面说了,要通过类似 byteenable 这样的 mask 信号,自己选择要读写哪个字节
    此时,32 根线(或者说 4 个字节),只有其中选中的字节会参与读写,没选中的字节(或位)被忽略掉而已
    leonshaw
        41
    leonshaw  
       2023-04-18 00:06:20 +08:00
    @OrdinaryMan #25 存储单元的位数决定了数据总线的条数——错
    RecursiveG
        42
    RecursiveG  
       2023-04-18 00:20:16 +08:00
    汉字是一个字一个框,如果要存二字词就需要两个框,如果要存人名就要三个框,存成语要四个框。
    存完成语我还可以问这个成语的第三个字是啥。
    tyzandhr
        43
    tyzandhr  
       2023-04-18 00:48:58 +08:00
    省流:一个字节长度为 1-48bit 不等。最初通常使用 6bit 或 9bit 为一个字节。from:维基百科
    DonaldY
        44
    DonaldY  
       2023-04-18 01:21:02 +08:00
    计算单位。
    一般说是字长,寄存器最大处理单位。
    aijam
        45
    aijam  
       2023-04-18 05:37:30 +08:00
    32/64 位的 CPU ,指的是用多少个 bit 代表一个内存地址。
    每个内存地址,指向的都是 1 byte(8 bit)的数据,这叫 word size 。
    所以 32 位的电脑,你最多有 2^32 个内存地址(0x00000000 to 0xffffffff)。每个地址存 1 byte ,最多有 2^32 byte=4GB ,这就是常说的 32 位电脑的最大内存限制。相应的 64 位电脑,理论最多能支持有 2^24 TB 内存,大约是 16 million TB 。
    polarbearn
        46
    polarbearn  
       2023-04-18 08:21:22 +08:00   ❤️ 1
    @Livid @raymanr chatGPT 回答
    raymanr
        47
    raymanr  
       2023-04-18 09:26:42 +08:00   ❤️ 1
    @polarbearn 有什么问题吗? 我贴个回答意思是告诉楼主, 这种事问 chatgpt 就行了, 而且回答内容我也是完全阅读了解认可并认为能够回答楼主的疑问的.
    raymanr
        48
    raymanr  
       2023-04-18 09:33:13 +08:00   ❤️ 1
    @polarbearn
    @009694
    算求, 以后老子还回答个屁的问题, chatgpt 组织了语言复制粘贴下, 就跟他妈行政查考勤一样闹麻了, 我他妈粘贴的是无意义的灌水内容还是怎么?? 你们了不起, 你们清高, 你们加油哈, 早日把 chatgpt 赶出 v2, 下回我看别人直接不贴 FROM CHATGPT 你们又要怎么个折腾.
    shendaowu
        49
    shendaowu  
       2023-04-18 09:47:49 +08:00
    感觉 OP 可能是对 CPU 的运行过程不太了解。我找了一会,找到个可视化的 CPU 模拟器:

    视频介绍:

    网址: https://eseo-tech.github.io/emulsiV/

    进去之后把 Animation 勾选上。然后点 run 或者 step 一步一步执行。这个模拟器好像没表示控制总线。

    应该是可以自己修改指令。不过这个指令集我不熟,没试。
    polarbearn
        50
    polarbearn  
       2023-04-18 10:01:51 +08:00   ❤️ 1
    009694
        51
    009694  
       2023-04-18 10:04:31 +08:00 via iPhone
    @raymanr 你自己看看这个回答有解决什么问题吗?拿一个满天飞的免费接口绕了一圈还感觉自己做了什么大善事。对这种客观问题问题 gpt 是很容易给出似是而非的错误答案的。 真想接 gpt 直接搞个爬虫效率比你这个人工粘贴高不知道多少
    42is42is42
        52
    42is42is42  
       2023-04-18 10:08:11 +08:00
    存储体:
    • 存储单元:每个存储单元存放一串二进制代码。
    • 存储字( word ):存储单元中二进制代码的组合。
    • 存储字长:存储单元中二进制代码的位数。
    • 存储元:存户二进制的电子元件(电容),每个存储元可存 1bit 。
    ButcherHu
        53
    ButcherHu  
       2023-04-18 10:10:25 +08:00
    按字节寻址,但是总线宽度不一样。可以理解为 mtu 是 1500 但是带宽是千兆。
    leimao
        54
    leimao  
       2023-04-18 10:11:27 +08:00
    工地里,阿宝力气很小,一趟只能搬一块砖。
    后来工地里又来了阿宏,阿宏力气很大,一趟能搬四块砖。
    后来工地里又来了阿彪,阿彪力气更大,一趟能搬八块砖。

    如果你让阿彪一趟只搬一块砖,那可就太浪费了。
    lostsquirrelX
        55
    lostsquirrelX  
       2023-04-18 11:39:20 +08:00
    字 Word cpu 决定长度
    字节 byte
    raymanr
        56
    raymanr  
       2023-04-18 11:45:12 +08:00
    @009694 搞笑, 那下面这么多人类回答解决楼主的疑惑了吗? 人笨怪答案是 chatgpt?
    raymanr
        57
    raymanr  
       2023-04-18 11:49:37 +08:00
    @009694 顺带一提, 你在这反对了半天我贴 chatgpt 组织的答案, 又解决了楼主什么问题呢?
    raymanr
        58
    raymanr  
       2023-04-18 12:04:04 +08:00
    @polarbearn 我只想问, 我贴个 FROM CHATGPT 你们自然可以跳脚不满, 我自己承认了嘛. 不过有人要是闲的发慌, 把稿子洗一洗, 不承认是 AI 生成, 看起来也不像 AI 生成, 你们又要如何应对呢?
    byron
        59
    byron  
       2023-04-18 13:06:15 +08:00   ❤️ 4
    你的疑问很好,的确按字节来说,一个字节有 8 位,对应 8 个二进制位。但是在计算机系统中,一个"字"的大小和一个字节是两个不同的概念。

    字节(Byte)是存储单元的大小,确实是 8 位,固定的。

    而字长(Word size)表示 CPU 在一次读 /写内存操作中能读取或写入的数据位数。它决定了 CPU 在同一时刻能操作的数据宽度。字长可以是 8 位,16 位,32 位,64 位等不同位数。

    所以,尽管内存是以字节为存储单元来划分的,但是 CPU 在访问内存时,一次可以访问多个字节,这就是字长的概念。

    32 位机和 64 位机之所以具有不同的字长,是因为它们的 CPU 及其寻址总线等硬件支持读取不同位数的数据。32 位 CPU 支持 32 位字长,可以一次读取 4 个字节(32 位)的数据;64 位 CPU 支持 64 位字长,可以一次读取 8 个字节(64 位)的数据。

    除字长外,与之对应的还有地址总线宽度。32 位机的地址总线宽度也是 32 位,所以其最大内存空间也就是 2^32 = 4GB 。64 位机的地址总线是 64 位,所以支持最大 16EB 的内存空间。

    所以,总结来说:

    1) 字节大小固定是 8 位,这是存储单元大小。

    2) 字长表示 CPU 一次可以访问的位数,可以是 8 位,16 位,32 位,64 位等。它决定了 CPU 的访问宽度和性能。

    3) 地址总线宽度对应字长,决定了系统可以支持的最大内存空间。

    希望通过上述解释,能帮助你理解计算机中的字节、字长和地址总线的概念,明白 32 位和 64 位系统的区别所在。如果还有不理解的地方,请继续提问,我很乐意阐述和讨论。
    ljpCN
        60
    ljpCN  
       2023-04-18 15:51:55 +08:00
    我宣布 #59 byron 老哥是最佳答案!
    ofblyt
        61
    ofblyt  
       2023-04-18 15:57:48 +08:00
    微机原理看看就懂了,8086cpu ,8251A ,8259 ,8255
    1vonzhang
        62
    1vonzhang  
       2023-04-18 18:58:36 +08:00   ❤️ 2
    很开心在 V2 看到这种讨论具体技术、理论的帖子顶上热门,这是我理想中 V2 的样子之一。

    看了你最新的回复,区分字和字节的概念是正确的,整体的理解还是有些抽象。

    我尝试举个例子。

    假设我有一大片空地(整个内存),上面建了一排紧挨着彼此、大小一样的仓库(内存单元),一共 256 个仓库从 0 (0x00) 到 255 (0xFF) 连续编号(内存地址)。

    如果我想让你去找到其中一间仓库,我需要给你一个 0 到 255 之间的门牌号。换成二进制就是 0000 0000 到 1111 1111 ,也就是说 [8 个二进制位就可以涵盖所有仓库] 。如果我只能把门牌号用 1 和 0 写在纸上(地址总线),而纸上只写的开 4 个二进制位,那我最多也只能写到 1111 (15),也就是说我没有办法指示你去 16~255 这些仓库;反过来,如果纸上最多能写上 16 个二进制位,因为我们最后一个仓库的门牌号是 255 (0000 0000 1111 1111),所以前八位永远是 0 ,永远用不到。

    这就是你在某层楼回复说的 [地址总线的条数决定寻址空间大小] 。每条线上可以是 1 也可以是 0 ,一条地址线就是一个二进制位。地址总线越宽(位数越多),能写开的门牌号就越多,能找到的仓库就越多。

    下面我们来区分“字节”和“字”。“字” 的概念但看内存没有意义,它主要来自于 [CPU 一次性处理的数据的大小(位宽)] 。

    假设我们有一个工厂( CPU ),投入**一份原料**或者两份(运算数),同时说明要做的操作(运算类型),就可以生产出相应的产品(运算结果)。有的工厂比较大 (64 bit CPU),一份原料需要 8 个仓库装,也有的比较小 (8 bit CPU),一份原料一间仓库就够。我们这里规定,在这个例子里,**一份原料**需要 4 个仓库才能放得下( 1 word == 4 bytes)。我们就约定,把每份原料存在相邻的四个仓库里,比如仓库 0~3 存放一份,4~7 存放一份。

    我们建仓库是因为有工厂,工厂是我们的核心,所以一切都以工厂运作的最小单位——一份原料的大小来定。这个就是“字” (word)。而“字节” (byte) 只是一间仓库的大小,永远是 8 位,和什么样的工厂没有关系。

    工厂有两个进货口,有些产品需要一种原材料 ( e.g. 一斤生鸡肉,在工厂 “加热” 的操作下,生产出一斤熟鸡肉),有些产品需要两种( e.g. 一斤生鸡肉+一斤油,在工厂“加热”的操作下,生产出一斤炸鸡)。这里注意,工厂的产品有可能还要当作新的原料加工别的产品,要运回仓库储存,所以一份产品的大小也是 4 间仓库。

    为了能*一次性*投入一整份材料(而不是 1/4 份、半份...),我们需要找到合适的卡车,一次性能装下一份原料、即四个仓库的卡车。用来运输原料(数据)的卡车就是**数据总线**。如果工厂投料生产的单位是 4 间仓库( 1 word == 4 bytes == 32 bits) 那么卡车的大小就是 4 间仓库 (数据总线是 32 位)。

    下面我们来解释一下你问题补充里说的“每次取出一个字的数据送到数据总线传给 CPU ”。特别是这个“每次”。

    这里需要一个背景知识。如果你没有学过数字电路,可以简单记住:电路的工作不是连续的,而是一下一下的,每一下都可以做一个最基本的动作。像一个“滴答滴答”走的时钟秒表。这个表走的越快(时钟频率越高),一定时间内能做的动作就越多。

    你的理解抽象的地方,在于这个“每次”。因为对于内存那边和 CPU 那边,“每次”的概念可能是不同的( CPU 操作和内存内部的操作用不同频率的时钟)。在仓库那边有一个仓库管理员,时钟每滴答一次,他就把当前门牌号对应的仓库装到卡车上,并把门牌号+1 。一次操作的基本单位是一个仓库(一个字节)。4 个滴答之后,卡车才能装满。而在工厂那边,有另一个时钟,每滴答一次,工厂就把进货口的两卡车原料加工成产品。一次操作的基本单位是一个卡车( 4 个字节)。

    当然了,如果一份材料就是一个仓库的大小,那么就不需要仓库管理员来管理“卡车到底装没装满”,因为卡车只能装一间仓库,装了就是装满,没装就是空的。那么这时候内存和 CPU 的时钟(或者“一次”)就是同样的速度、甚至可以用同一个钟。如果你不关心仓库里面具体发生了什么,只是从工厂的角度看,那么可以认为,工厂每运作一次,就有一卡车新的原料从仓库里出来,他们的“一次“也是一样的。

    59 楼说的很好,他说的 “CPU 在访问内存时,一次可以访问多个字节,这就是字长的概念”,其实就是从内存外部,从 CPU 的角度看的,也确实是你在弄清楚具体内部细节之后,应该保持的角度。只是这种从外部看的角度不足以解释你对”8 位的储存怎么*一下子*取出 32 位甚至 64 位的数据“的疑问。

    这里我们只讨论了数据内存,其实指令内存也是类似的,不管是冯诺依曼架构(放指令的和放数据的是两套不同的仓库)还是哈佛架构(同一片仓库,规定某些仓库用来放指令,某些仓库用来放数据)。题主读到取指令的时候,特别是有的指令很长、需要存放在两个连续的单元、读两次之后再执行指令,应该就能够更好的理解储存单元大小(字节)和运算单元大小(字)之间的差异了。



    这个例子有很多不严谨的地方,因为主要目的是提供一个符合直觉的、具象的理解。题主学习计组主要目的也是从概念层面上理解计算机的组成,而不是现实生活中计算机具体是怎么造的。
    例如:
    - 字节永远是 8 位只是针对绝大多数通用计算机来说。
    - 64 位 CPU 的计算机并没有 64 位地址线,因为没有那么大的内存,高位的地址线永远是 0 。
    - CPU 和 ALU 在这个例子里当作了同一个东西处理,但其实数据加载到 CPU 的寄存器内,和 ALU 读取寄存器数据进行运算,是不同的事情。
    - 内存和 CPU 速度不一样并不需要两个时钟,只要 CPU 每 4 个时钟周期才运算一次,就可以达到例子里的同步。现实生活中根据指令的不同,CPU 每几个时钟周期运算一次并不是固定的。
    - ……
    kkkbbb
        63
    kkkbbb  
       2023-04-18 20:12:15 +08:00
    @shendaowu 请教下视频怎么回复的?
    OrdinaryMan
        64
    OrdinaryMan  
    OP
       2023-04-18 20:49:44 +08:00 via Android
    @1vonzhang 说的很清楚,感谢
    secondwtq
        65
    secondwtq  
       2023-04-18 23:45:01 +08:00
    @kkkbbb 你直接贴视频链接就行
    其实有时候挺烦的 ... 经常打乱回复排版,就像公众号文章两句话一个图的感觉一样
    secondwtq
        66
    secondwtq  
       2023-04-18 23:50:02 +08:00
    相对于“字节”来说,“字”的概念貌似不那么绝对
    比如现代 CPU 通过 SIMD 能访问 16/32/64 字节的数据,也没人说它是 512 位 CPU
    相对来说我更喜欢把重点放在寄存器大小和地址大小上,虽然一般这俩和“字”在数值上是一样的
    Livid
        67
    Livid  
    MOD
       2023-04-19 00:25:54 +08:00
    @polarbearn 谢谢,那个贴 ChatGPT 回复的账号已经被彻底 ban 。
    shendaowu
        68
    shendaowu  
       2023-04-19 10:10:35 +08:00
    #63 @kkkbbb 有人回复了,我就只补充一下。好像只支持 Youtube 。
    kkkbbb
        69
    kkkbbb  
       2023-04-19 11:00:06 +08:00
    @secondwtq 好的,谢谢
    kkkbbb
        70
    kkkbbb  
       2023-04-19 11:01:22 +08:00
    @shendaowu 是么。。我还想着试下那 o(╯□╰)o
    Yeen
        71
    Yeen  
       2023-04-19 16:08:29 +08:00
    字节是最小存储单元。
    字是基于字节的扩展存储单元的扩展。
    shendaowu
        72
    shendaowu  
       2023-04-19 17:53:13 +08:00
    @kkkbbb 我不太确定。想测试的话可以到这里: https://www.v2ex.com/go/sandbox 。跟正常发帖一样都是花费积分的。
    kkkbbb
        73
    kkkbbb  
       2023-04-20 09:34:15 +08:00
    @shendaowu 谢谢
    GoldenSheep
        74
    GoldenSheep  
       2023-04-27 08:40:48 +08:00
    可以看一眼王爽的汇编书,里面提到一个 8bit 是一个存储单元,而可以同时使用多个存储单元存储数据,至于地址线的话,有个地址加法器来计算的,cpu 的位数代表的是一次处理的最大数据量,我的理解是这样的,下面是我自己的一些笔记,也不知道是不是有什么错的地方,往大佬指出
    @OrdinaryMan


    https://www.glodensheep.top/2023/04/24/16-Assembly/02-%E5%AF%84%E5%AD%98%E5%99%A8/#16%E4%BD%8D%E7%9A%84CPU
    unlsycn
        75
    unlsycn  
       2023-05-06 09:25:28 +08:00 via Android
    @Pil0tXia 不是这样。处理器位宽实际上代表的是通用寄存器宽度。由于访存指令寻址是通过寄存器中的数据进行,自然无法访问超过位宽的地址。但是对于 64 位的计算机而言,地址总线可能只有 48 位,因为不存在那么大的内存去管理。但其寄存器位宽是 64 位。
    unlsycn
        76
    unlsycn  
       2023-05-06 09:27:20 +08:00 via Android
    另外,关于字( Word ),实际上不一定代表处理器的位宽。比如在 RV64 中,Word 就是指 32 位,64 位的访存指令 ld 是 Load Doubleword 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   926 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 22:16 · PVG 06:16 · LAX 14:16 · JFK 17:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.