为什么我们可以在O(1)中访问我们记忆中的某个地方?
答案 0 :(得分:3)
快速回答:你做不到!
然而,可以通过直接访问来解决系统的主存储器,即板上的芯片。只需提供正确的地址,总线将返回该位置的内存(可能在一个块中)。
一旦进入CPU,内存访问就会大不相同。有几个缓存,几个带缓存的内核,以及可能还有其他带缓存的CPU。虽然可以直接访问主内存,但速度很慢,这就是我们拥有所有这些缓存的原因。但现在这意味着在CPU内部无法直接访问内存。
当CPU需要访问内存时,它进入查找模式。它还有一个锁定系统,可以正确地共享缓存之间的内存。根据您是在读取还是写入,以及该内存的最新缓存所在的位置,不同的地址实际上会占用不同的时间段。这就是所谓的NUMA(非统一内存访问)。虽然这里的时间复杂度可能受一个常数的约束(因此可能是/技术上的O(1)),但它可能不是大多数人所认为的恒定时间。
这比这复杂得多。 CPU为内存提供页表,以便操作系统可以为应用程序提供虚拟内存(即,它可以对地址空间进行分区)并按需加载内存。这些表是类似地图的结构。当您访问内存时,CPU会决定是否加载了您想要的地址,或者操作系统是否必须先检索它。这些映射是总内存大小的函数,因此不是线性时间,尽管很可能是分摊的常量时间。 (如果您正在运行虚拟机,则可以在此处添加另一层表 - 这是VM运行速度稍慢的一个原因。)
这只是一个简短的概述。希望足以让你觉得内存访问不是真正的时间,而是取决于很多东西。但请记住,在这些级别上采用了如此多的优化,以至于高级C程序可能看起来可以持续访问。
答案 1 :(得分:1)
现代计算机系统中的内存是随机访问,因此只要您知道需要访问的内存地址,计算机就可以直接进入该内存位置并读取/写入该位置。
这与某些[旧]系统(例如磁带存储器)相反,磁带必须通过物理假脱机来访问某些区域,因此更远的位置需要更长的时间才能访问。
不确定在O(1)中分配是什么意思,因为在每天计算机上处理典型的堆时,分配内存通常不是O(1)。
答案 2 :(得分:0)
这取决于你使用的计算模型,在图灵机模型中,两个操作都不是O(1),在随机访问模型中,访问是O(1),因为大多数是现代的使用RAM的硬件使该模型很有用。我假设你使用的模型为了简单起见也允许O(1)分配作为在轻量内存使用负载下的机器上的大多数现代实现的近似。
答案 3 :(得分:0)
为什么可以在O(1)中访问?因为内存访问是通过地址。如果您知道要访问的地址,那么硬件可以直接访问它并在一次操作中获取任何内容。
至于分配是O(1),我不确定总是如此。由操作系统来分配新的内存块,并且它用于执行该操作的算法在所有情况下可能不一定是O(1)。例如,如果您请求大块内存并且没有足够大的连续块来满足请求,则操作系统可能会执行诸如分页其他数据或从其他进程重定位信息以创建足够大的连续块以执行此操作的操作。满足要求。
虽然如果你想将极其简化的分配视图视为“返回可用内存的第一个字节的地址”,那么很容易理解为什么这可能是O(1)操作。系统只需要返回最后分配的字节的地址+ 1,因此只要它跟踪每次分配后最后分配的字节,并且只要你假设一个无限的内存空间,那么计算下一个空闲地址总是O(1)。