字大小是否限制内存地址的数量,而不是内存本身?
Does word size limit number of memory addresses, not the memory itself?
我正在阅读有关单词大小的信息,它指出以下内容:
每台计算机都有一个字大小,表示一个 指针数据。由于虚拟地址是由这样的单词编码的,因此 由字大小决定的最重要的系统参数是 虚拟地址空间的最大大小。也就是说,对于具有 W位字大小,虚拟地址的范围可以从0到2^W-1
32 位字大小将虚拟地址空间限制为 4 GB, 也就是说,刚刚超过 4 x 10^9 字节。
我的理解是否正确,即是可能的地址数,而不是总内存大小?例如,如果一个单词是 2 位,那么我将有 4 个地址(2^2)
,但是,放置在这些地址中的内容可能具有更大的大小。我可以访问总共 1GB 的struct
,并将其放在address[0]
下,这样即使地址限制为 2 位,内存也超过 1GB。
计算机内部有一个地址总线和一个数据总线。地址总线和数据总线不是同一总线 - 例如,您可以有一个 16 位地址总线和一个 32 位数据总线。可能的地址数为 65536,如果是字寻址计算机,则总内存大小为 262144 字节(65536 字,= 65536*4),如果是字节寻址计算机,则为 65536 字节。
如今,大多数CPU都是字节寻址的,一些旧的大型机和超级计算机(例如旧的Crays)是单词寻址的。在字寻址机器上,无论如何都没有"字节"的真正概念,因此内存大小是用单词引用的。
实际上,字节已经成为公认的有用的最小内存单位;不太小,也不太大。例如,对于相同大小的内存,位寻址机器需要宽8倍的内存总线(非常不方便),而64位字会使许多通用计算浪费。
一切都是真的
具有讽刺意味的是,缓存和DDR内存的设计意味着,当您的程序寻址单个字节时,整个缓存行的数据将通过数据总线从DDR加载。 DDR4的数据总线宽度为64位,因此当程序访问单个字节时,至少加载64位。所以你的程序"认为"它生活在字节寻址的环境中,但内存接口的物理现实是它是64位字寻址的。
你的书并不完全真实,但作为一个一般的简单规则,它相当有效。
今天常见的例外是,你可以有一个大于地址范围的字大小,例如在大多数 64 位 CPU 中(我知道的足够详细来理解地址范围) - x86-64 例如,有一个 48 位虚拟地址范围,我相信在技术上可以扩展到 53 位。要走得更远,就需要在机器中对页表布局进行新的设计,因此根本不是微不足道的更改。位于 48 位之外的地址(实际上是 47 位,然后第 48 个顶部(或符号)位扩展到剩余的 16 位,确保没有人将前 16 位用于"聪明的东西",如果/当地址范围扩展时,会导致架构中断)。AArch64(ARM的64位处理器架构)也只使用64位中的一部分作为虚拟地址 - 我认为这里也是48位。
另一方面,25+ 年前,当 16 位 x86 计算机成为标准时,它们可以寻址超过 16 位的"字",这要归功于段寄存器移动 4 位然后添加到 16 位寄存器值,这允许 20 位地址范围 [1] - 或在保护模式下的 80286 处理器, 段寄存器包含一个段描述符表的索引,该表具有基址,该基址被添加到常规寄存器值中,总共给出一个 24 位地址。
当然,许多处理器的物理地址范围比虚拟地址的物理地址范围更严格,因为将用于寻址内存的引脚放在处理器外部是"昂贵的"。 68000 是 32 位处理器,但只有 24 个地址引脚。早期的x86-64处理器只有40位地址引脚,提供64GB的内存范围。
[1] 实际上有点过分了,因为您可以将低四位零添加到 16 位值中,从而添加一个 20 位值。
- 我在 IDA 或 dbg 或 olly 上看到的内存是否与我在 RAM 上实时加载的内存相同?
- 访问"std::vector"的保留但未调整大小的内存作为原始内存是否安全?
- 本地分配的内存是否可以用于将来使用?
- 多次分配内存是否一次性需要更多时间?
- 删除矢量的尾部(通过擦除)内存是否有效
- 如何找出内存是否属于堆或堆栈
- C++:提升:托管共享内存是否需要信号量锁
- 在 C/C++ 中在特定地址边界上对齐内存是否仍能提高 x86 性能?
- 检查内存是否在堆上
- C++内存 - 是否需要删除使用 'new' 创建的基元类型变量?
- 如果通过委托给“malloc”的重载“new[]”分配,“释放”内存是否安全
- 分配给 cpp 中定义的全局静态变量的内存是否在 C++ 中删除其类的实例后释放
- 我的 265GB RAM 笔记本电脑上的内存是否超过 8GB
- 在动态内存分配中,在程序终止并且忘记释放内存后,该内存是否保持分配状态
- 这些二维数组(C++)的内存是否不足
- 如果我在 for 中声明一个对象,它的内存是否会在那之后被释放?
- 二进制搜索树(如何在插入时检查内存是否不足)
- 用new重新分配内存是否安全
- 在构造函数初始化列表中分配内存是否存在任何问题
- 内存映射内存是否可能