提问人:Htam 提问时间:10/28/2023 更新时间:10/30/2023 访问量:51
阵列访问不是恒定的
Array access is not constant
问:
假设我们有一个数组 A,它的第一个元素是带有地址 adr 的元素。 当我们想访问第 n 个元素时,在机器级别,我们必须首先计算 adr + n*a[size],然后访问该元素。
正如我们所看到的,第 n 个元素地址的计算取决于 n,而大 n 意味着更多的计算步骤
那么为什么说访问数组是恒定时间呢?
我搜索为什么会这样,但我没有找到
答:
是的,在某些处理器上,较大数字的乘法可能需要更长的时间,尽管现在我们在这里谈论的是一些额外的周期,即使是非常非常大的数字。换句话说,乘法确实可以很好地扩展。
即使使用移位和加法方法,我们也可以将乘法的复杂性设置为最大值,例如移位-加法循环的 32 或 64 次迭代。
正如我们所看到的,第 n 个元素地址的计算取决于 n,而大 n 意味着更多的计算步骤
数组索引使用以下类型完成:
指向数组开头的基指针,程序和处理器将其视为无符号整数,其大小是处理器的地址宽度(例如,64 位或 32 位,具体取决于处理器)。
数组的索引,需要按数组元素的大小进行缩放,该索引最终也被限制为与上述基指针相同的位宽。
我想指出的是,在我们谈论内置数组机制的大多数语言中,没有办法分配数组索引计算将溢出固定位宽的数组。分配将失败,请求的内存超过处理器可以寻址的内存。因此,这意味着所有访问有效内存(即分配成功)的索引和指针算术运算都不会溢出,并且不需要在计算中检查溢出。(除非索引操作使用小于处理器无符号位宽度的大小来完成,可悲的是,这可能是由程序员的选择和/或语言默认值引起的。
由于无法分配超出处理器寻址能力的数组,因此我们可以在索引计算中使用固定大小的算术。正因为如此,我们知道处理器可以在 O(1) 中执行这样的索引。
评论
上一个:洗白指针会破坏优化机会吗?
评论
8 * 10
2 * 10
n