![每字节 RAM 内存访问](https://linux22.com/image/1238325/%E6%AF%8F%E5%AD%97%E8%8A%82%20RAM%20%E5%86%85%E5%AD%98%E8%AE%BF%E9%97%AE.png)
我有一个简单的问题。如今,内存 DDR 芯片的宽度为 64 位,CPU 数据总线的宽度也是 64 位。但内存仍然以单字节形式组织。因此,我想问的是,当 CPU 选择某个内存地址时,它应该是一个字节,对吗?因为您可以访问的最低内存部分是 1 个字节。但是,如果每个地址获得 1 个字节,那么为什么内存总线的宽度是 8 个字节?
答案1
我们将计算机架构称为byte-addressable
——意思是,内存以字节为单位寻址。这有助于我们一次提取 8 位数据。但是,这并不总是常态,还会使用其他宽度。
事实上,即使您使用基于 Intel 的字节地址计算机,您使用的内存通常也以不同的宽度进行访问(如您的示例中的 64 位)。
这有助于用较少的地址空间来处理大量数据。
我的回答实际上到此已经完成了,但是,我进一步讨论了如何进行内存访问,这可能有助于思考所实现的抽象(也许还能激励您阅读更多有关内存的内容)。
如果您见过 DDR-RAM 内存条,您会记得在绿色 PCB 上看到过几个芯片。这些芯片被条带化在一起,以便并行访问。这让您的 RAM 访问速度更快。
RAM 模块前面是内存控制器。它旨在以更宽的位宽(32、64、128 位 - 取决于设计)访问数据。
当你从这个内存空间访问一个字节时,内存控制器实际上得到的是一个完整的“内存字”;这里的一个字实际上是内存控制器这次访问的宽度。
这意味着如果它的宽度为 128 位,您总是从 16 的倍数的地址获取 16 个字节。
那么,现在当您想要地址 18(= 16+2)处的字节时会发生什么?
好吧,您从地址 16 获得 16 个字节并丢弃其中的 15 个!
更有趣的是,当你想在地址 19 写入一个字节时会发生什么?
你从地址 16 获取 16 个字节,更改第 3 个(第 19 个地址)字节,然后写回所有这 16 个字节(有趣吧?)。
所有这些都需要付出很大努力。内存控制器就是为管理这些而设计的,它实际上可以并行处理多个请求。
我们甚至还没有谈论“双通道”:-)
以下是来自维基百科的参考DDR SDRAM 组织
PC3200 是 DDR SDRAM,设计为使用 DDR-400 芯片以 200 MHz 运行,
带宽为 3,200 MB/s。由于内存是双泵的,
这意味着 PC3200 内存的有效时钟频率为 400 MHz。1 GB PC3200 非 ECC 模块通常由 16 个 512 Mbit 芯片组成,
每侧 8 个(512 Mbit × 16 个芯片)/(8 位(每字节))= 1,024 MB。
组成 1 GB 内存模块的单个芯片通常
以 64 Mbit 为单位组织,每个芯片的数据宽度为 8 位,
通常表示为 64M×8。以这种方式制造的内存是低密度 RAM,通常
与任何指定 PC3200 DDR-400 内存的主板兼容。
来自内存控制器页
总线宽度是与内存单元通信可用的并行线路数量。
内存控制器的总线宽度范围从早期系统中的 8 位到更复杂的系统和视频卡中的 512 位(通常实现为四个并行运行的 64 位同步内存控制器,但有些设计为以“组合模式”运行,其中两个 64 位内存控制器可用于访问 128 位内存设备)。
答案2
一次传输 8 个字节的大量数据比传输 1 个字节的速度更快。此外,实际上没有办法在 CPU 缓存之外寻址单个字节,因为最后几个地址位不再具有物理连接(因为不需要它们)。
答案3
我讲的不是很专业,但大致上...
处理器每次检索一个字(即 64 位处理器每次检索 8 个字节)。但是,检索单个字节时,它们实际上会丢弃其他 7 个字节。内存寻址方案通常仍以字节为单位,但如果您尽可能快地提取数据,则可以使用字对齐地址,即可被字长(以字节为单位)整除的地址。在 64 位系统中,您将使用地址 0、8、16、24 等。
如果从非字对齐的地址(例如 5)中提取一个字,则处理器必须进行两次提取,一次提取字节 5、6、7,第二次提取字节 8、9、10、11、12,因此将花费两倍的时间。
出于各种原因,单独寻址字节很有用,但很容易想象出一种处理器设计,它采用字寻址。如果您想要一个字节,您将得到一个字,删除您不想要的字节,然后将字节移动到字的底部。在某种程度上,这就是正在发生的事情,获取一个字节就是获取一个字,然后从中挑选一个字节,将它视为地址 10 处的字节而不是字 1、字节 3 更容易。
在 CPU 之外,RAM 永远看不到较低的地址位,RAM 被组织为字,正是 CPU/程序员模型提供了字节寻址的幻觉。
答案4
从我从事汇编语言和底层硬件工作的经历来看,内存实际上是按页访问的。您实际上永远不会访问单个字节,甚至不会访问 RAM 的总线宽度,而是按块访问(我无法给出确切的数字 — — 尤其是因为它会变化 — — 但 4KB 这个数字听起来很熟悉 [也许我在考虑段,尽管它是 64KB])。
关键在于,寻址单个字节的效率非常低,尤其是因为下一个要访问的内存地址很可能就在它旁边。因此,当您访问一个字节时,系统会缓存一个 RAM 块(您认为各种 CPU 缓存是做什么用的?)您所做的任何更改都会对该缓存的 RAM 进行,因此如果您将其写回,它可以快速而顺利地写入该块。该字节是单独访问的,但来自缓存的块;也就是说,CPU 不会获取单个字节,而是只返回一个字节。
由于当今的系统规模越来越大,我想它们将需要更多的缓存来优化(因此需要更大的 CPU 缓存)。