使用 32 位处理器和 1gb ram 可以获得多少内存地址?

joh*_*han 14 memory cpu 64-bit 32-bit

使用 32 位处理器和 1gb ram 可以获得多少内存地址,使用 64 位处理器可以获得多少内存地址?

我认为它是这样的:

1GB 的内存除以 32 位还是除以 4?获取内存地址的数量?

但我不确定。这就是为什么我要问。

我在维基百科上指出,1 个内存地址是 32 位宽或 4 个八位字节(1 个八位字节 = 8 位),而 64 位处理器中 1 个内存地址或 1 个整数是 64 位宽或 8 个八位字节。但不知道我是否理解正确。

gro*_*taj 44

简短回答:可用地址的数量等于这些地址中的较小者:

  • 内存大小(以字节为单位)
  • 可以保存在 CPU 机器字中的最大无符号整数

上面的长答案和解释:

内存由字节 (B) 组成。每个字节由 8 位 (b) 组成。

1 B = 8 b
Run Code Online (Sandbox Code Playgroud)

1 GB 的 RAM 实际上是 1 GiB(千兆字节,而不是千兆字节)。区别在于:

1 GB  = 10^9 B = 1 000 000 000 B
1 GiB = 2^30 B = 1 073 741 824 B
Run Code Online (Sandbox Code Playgroud)

无论 CPU 机器字有多大,内存的每个字节都有自己的地址。例如。Intel 8086 CPU 是 16 位的,它按字节寻址内存,现代 32 位和 64 位 CPU 也是如此。这就是第一个限制的原因——地址不能多于内存字节。

内存地址只是 CPU 必须从内存的开头跳过才能到达它正在寻找的字节数。

  • 要访问第一个字节,它必须跳过 0 个字节,因此第一个字节的地址是 0。
  • 要访问第二个字节,它必须跳过 1 个字节,因此其地址为 1。
  • (等等……)
  • 为了访问最后一个字节,CPU 跳过了 1073741823 个字节,所以它的地址是 1073741823。

现在您必须知道 32 位实际上意味着什么。正如我之前提到的,它是一个机器字的大小。

机器字是 CPU 用来保存数字(在 RAM、缓存或内部寄存器中)的内存量。32 位 CPU 使用 32 位(4 个字节)来保存数字。内存地址也是数字,因此在 32 位 CPU 上,内存地址由 32 位组成。

现在想一想:如果你有一位,你可以在上面保存两个值:0 或 1。再加一位,你有四个值:0、1、2、3。在三个位上,你可以保存八个值: 0, 1, 2... 6, 7. 这实际上是一个二进制系统,它的工作原理是这样的:

Decimal Binary
0       0000
1       0001
2       0010
3       0011
4       0100
5       0101
6       0110
7       0111
8       1000
9       1001
10      1010
11      1011
12      1100
13      1101
14      1110
15      1111
Run Code Online (Sandbox Code Playgroud)

它的工作原理与通常的加法完全一样,但最大数字是 1,而不是 9。十进制 0 是0000,然后加 1 得到0001,再加一得到0010。这里发生的事情就像有小数09并加一个:你把 9 改为 0 并增加下一个数字。

从上面的示例中,您可以看到始终有一个最大值可以保留在具有恒定位数的数字中 - 因为当所有位均为 1 并且您尝试将值增加 1 时,所有位都将变为 0,从而破坏数字。它被称为整数溢出,会导致许多令人不快的问题,对用户和开发人员来说都是如此。

   11111111    = 255
+         1
-----------
  100000000    = 0   (9 bits here, so 1 is trimmed)
Run Code Online (Sandbox Code Playgroud)
  • 对于 1 位,最大值为 1,
  • 2 位 - 3,
  • 3 位 - 7,
  • 4 位 - 15

最大可能的数字总是 2^N-1,其中 N 是位数。正如我之前所说,内存地址是一个数字,它也有一个最大值。这就是为什么机器字的大小也是可用内存地址数量的限制 - 有时您的 CPU 无法处理足够大的数字来寻址更多内存。

因此,在 32 位上,您可以保留 0 到 2^32-1 之间的数字,即 4 294 967 295。它比 1 GB RAM 中的最大地址还多,因此在您的特定情况下,RAM 数量将成为限制因素。

32 位 CPU 的 RAM 限制理论上为 4 GB (2^32),而 64 位 CPU 的 RAM 限制为 16 EB(艾字节,1 EB = 2^30 GB)。换句话说,64 位 CPU 可以处理整个 Internet... 200 次 ;)(由WolframAlpha估计)。

但是,在实际操作系统中,32 位 CPU 可以处理大约 3 GiB 的 RAM。那是因为操作系统的内部架构 - 一些地址被保留用于其他目的。您可以在 Wikipedia 上阅读有关此所谓3 GB 障碍的更多信息。您可以使用Physical Address Extension解除此限制。


说到内存寻址,有几件事我要提一下:虚拟内存分段分页

虚拟内存

正如@Daniel R Hicks 在另一个答案中指出的那样,操作系统使用虚拟内存。这意味着应用程序实际上并不在实际内存地址上运行,而是在操作系统提供的内存地址上运行。

这种技术允许操作系统将一些数据从 RAM 移动到所谓的页面文件 (Windows) 或交换 (*NIX)。HDD 比 RAM 慢几个数量级,但对于很少访问的数据来说这不是一个严重的问题,它允许操作系统为应用程序提供比您实际安装的更多的 RAM。

分页

到目前为止我们所谈论的称为平面寻址方案。

分页是另一种寻址方案,它允许寻址更多内存,而您通常可以在平面模型中使用一个机器字来寻址。

想象一本书充满了 4 个字母的单词。假设每页有 1024 个数字。要寻址一个数字,您必须知道两件事:

  • 打印该单词的页数。
  • 该页面上的哪个词是您要查找的词。

现在这正是现代 x86 CPU 处理内存的方式。它分为 4 KiB 页(每页 1024 个机器字),这些页有编号。(实际上页面也可以是 4 MiB 大或带有PAE 的2 MiB )。当您想寻址内存单元时,您需要该页中的页码和地址。请注意,每个内存单元都由一对数字引用,这不是分段的情况。

分割

嗯,这与分页非常相似。它用于 Intel 8086,仅举一个例子。地址组现在称为内存段,而不是页。不同之处在于段可以重叠,而且它们确实重叠了很多。例如,在 8086 上,大多数存储单元可从 4096 个不同的段中获得。


一个例子:

假设我们有 8 个字节的内存,除了第 4 个字节等于 255 之外,所有字节都保持为零。

平面内存模型图示:

 _____
|  0  |
|  0  |
|  0  |
| 255 |
|  0  |
|  0  |
|  0  |
|  0  |
 -----
Run Code Online (Sandbox Code Playgroud)

具有 4 字节页面的分页内存示意图

 PAGE0
 _____
|  0  |
|  0  |
|  0  |  PAGE1
| 255 |  _____
 -----  |  0  |
        |  0  |
        |  0  |
        |  0  |
         -----
Run Code Online (Sandbox Code Playgroud)

4 字节段移位 1 的分段内存示意图

 SEG 0
 _____   SEG 1
|  0  |  _____   SEG 2
|  0  | |  0  |  _____   SEG 3
|  0  | |  0  | |  0  |  _____   SEG 4
| 255 | | 255 | | 255 | | 255 |  _____   SEG 5
 -----  |  0  | |  0  | |  0  | |  0  |  _____   SEG 6
         -----  |  0  | |  0  | |  0  | |  0  |  _____   SEG 7
                 -----  |  0  | |  0  | |  0  | |  0  |  _____
                         -----  |  0  | |  0  | |  0  | |  0  |
                                 -----   -----   -----   -----
Run Code Online (Sandbox Code Playgroud)

如您所见,第 4 个字节可以通过四种方式寻址:(从 0 开始寻址)

  • 段 0,偏移 3
  • 段 1,偏移 2
  • 第 2 段,偏移 1
  • 第 3 段,偏移量 0

它总是同一个记忆单元。

在现实生活中,段被移位超过 1 个字节(对于 8086,它是 16 个字节)。

分段的不好之处在于它很复杂(但我想您已经知道了;)好的地方在于您可以使用一些巧妙的技术来创建模块化程序。

例如,您可以将某个模块加载到一个段中,然后假设该段比实际小(刚好足以容纳该模块),然后选择第一个不与该伪较小的段重叠的段并加载下一个模块, 等等。基本上你通过这种方式得到的是可变大小的页面。


归档时间:

查看次数:

120807 次

最近记录:

8 年 前