【问题标题】:What happens at a hardware level when I access an element of an array?当我访问数组的元素时,硬件级别会发生什么?
【发布时间】:2015-01-09 23:02:35
【问题描述】:
int arr [] = {69, 1, 12, 10, 20, 113};

当我这样做时会发生什么

int x = a[3];

??????

我一直觉得a[3] 的意思是:

"从内存地址arr开始。 向前走 3 个内存地址。 获取该内存地址处表示的整数。"

但是我对哈希表的工作方式感到困惑。因为如果哈希表被实现为一个“桶”数组(就像教授在本次讲座中所说:https://www.youtube.com/watch?v=UPo-M8bzRrc),那么你仍然需要走到你需要的桶;因此,它们的访问效率并不比数组高。

谁能帮我解决这个问题?

【问题讨论】:

  • 您不会“步行”到数组元素 - 您只需在数组的基地址上添加一个偏移量,然后为您提供元素的地址。您可以这样做的原因是因为数组中的所有元素都具有相同的大小(相同的字节数)。
  • 哈希表的要点是键不必是索引。
  • 如果您已经知道要从数组中获得哪个索引,那么基本上没有什么更快的了。哈希表基本上可以让您更轻松地确定在表中搜索值时要使用(或从哪个索引开始)。
  • 编写一个简单的程序并阅读它的汇编列表是了解它如何工作的新知识的好方法。 (我并不是建议你不要问。)
  • 散列很有用,因为键不必是整数。

标签: c++ arrays hashtable


【解决方案1】:

将内存想象成一个大的两列表格:

+---------+-------+
| ADDRESS | VALUE |
+---------+-------+
|     ... |   ... |
+---------+-------+
|     100 |    69 |  <-- &arr[0] is 100
+---------+-------+
|     101 |     1 |
+---------+-------+
|     102 |    12 |
+---------+-------+
|     103 |    10 |  <-- &arr[3] is 103
+---------+-------+
|     104 |    20 |
+---------+-------+
|     105 |   113 |
+---------+-------+
|     ... |   ... |
+---------+-------+

我想强调的是,这是一个高度简化的模型,但它应该让您了解正在发生的事情。您的计算机知道您的阵列开始于,例如 地址 100。而且,由于给定数组中的所有元素都具有相同的大小,因此您可以通过将 +3 添加到起始地址来轻松访问数组的第三个元素。计算机不需要“步行”到数组的第三个元素,它只是抓取存储在内存中地址 100 + 3 的值。

如果您想查看此示例的实际效果,请编译并运行以下代码:

#include <iostream>
using namespace std;

int main() {
    int a[] = { 1, 2, 3 };
    cout << "Address of a:\t\t" << &a[0] << endl;
    cout << "Address of a[2]:\t" << &a[2] << endl;
    return 0;
}

记下a的地址。假设您的计算机使用 32 位整数,您应该看到 a[2] 的地址就是 a + 2*4 的地址。它添加 2*4 而不仅仅是 2 的原因是因为每个整数实际上使用 4 个字节的内存(即单个值将跨越 4 个地址)。

【讨论】:

    【解决方案2】:
    int x = a[3];
    

    硬件做(a的地址)+(3*sizeof(int))

    这是一种标准的索引操作,通常可以使用专用硬件一步完成。

    【讨论】:

      【解决方案3】:

      如果你这样写:

      int x = a[3];
      

      然后编译器在编译时就知道在哪里寻找变量,因此它可以在编译时设置相对和精确的内存位置。处理器不需要计算变量在内存中的位置。

      "从内存地址arr开始。向前走3个内存地址。得到 该内存地址处表示的整数。”

      所以基本上,这是真的,但这样写只是为了教育目的。 在这种情况下,处理器不会这样做。

      当你通过哈希表访问一个元素时,会根据键计算一个哈希值。许多键可能导致相同的哈希值。因此,必须有一个地方存储许多具有相同哈希值的对象,那个地方称为 bucket。因为存储桶中可能有许多对象,所以必须搜索所有对象以查找您要查找的值,但它仍然比存储在数组中的所有值更快的解决方案(您必须遍历其所有元素) .

      【讨论】:

      • 编译器不知道局部变量在哪里。它所知道的只是它们与堆栈帧基指针的偏移量。访问本地数组的元素需要一些运行时计算,即使索引是常量。
      【解决方案4】:

      这基本上就是数组访问的工作原理,它非常快。哈希表并不比数组快;事实上,正是因为它们接近于与数组一样快,所以它们被认为非常快。哈希表的主要优点是您可以使用任何可哈希类型作为键,而不仅仅是整数。此外,它们支持稀疏数据,中间没有一堆浪费的数组空间。

      【讨论】:

        【解决方案5】:

        它们的访问效率并不比数组高。

        这没什么好说的,因为数组的速度非常快。索引一个数组(即从一个对象到该数组中的另一个随机对象)是 O(1) - 一个单一的加法操作。大多数处理器甚至都有专门的指令来索引各种形式的数组和子对象,这些指令可以做得更好。

        处理器不会在途中遍历每个地址——它会跳过它们,不管有多少。 “与数组访问一样高效”确实受到高度赞扬。

        【讨论】:

          猜你喜欢
          • 2015-08-31
          • 1970-01-01
          • 2014-08-05
          • 2013-01-16
          • 1970-01-01
          • 2010-10-28
          • 2017-02-07
          • 1970-01-01
          • 2011-08-25
          相关资源
          最近更新 更多