其他人指出,您正在阅读的这本书已经很老了,所以它告诉您的有关指令时间的内容与今天并不真正相关。关于“内存周期”和“时钟周期”等价的那一点尤其可以追溯到 80 年代初。
一条指令执行需要多少时钟周期取决于指令触发的数据依赖关系,以及 CPU 指令集设计人员在优化指令解码和执行方面的重点。
许多较旧的机器会使用很多时钟来获取和解码复杂的指令,然后通常会使用几个时钟来访问内存(80 年代后期的时钟频率为 10 Mhz)。许多时钟解码是由复杂的指令集设计、缺乏大量资源(空间和晶体管)来进行指令解码以及通过更大的硅几何形状造成的长时间延迟造成的。存储器的访问时间为 70 ns,因此只需要几个时钟(例如 10 个),因为时钟周期要慢得多。
在实现上比现代 CPU 简单得多,CPU 内部通常有一个简单的有限状态机来控制指令执行。通过大致了解此 FSA 的工作原理,您可以预测指令解码时间,包括解码内存寻址的时间,正如您的书所建议的那样。不再正确。
现代机器的时钟频率非常高:2-4 Ghz。这就像 1000 倍一样快。这是可能的,因为晶体管要小得多,因此电流通过它们所需的时间更少。此外,由于晶体管数量众多,设计人员可以在解码/执行和缓存方面投入大量额外的硅。奇怪的是,记忆并没有变得更快,因此以时钟为单位访问记忆所需的相对时间出人意料地增加了。 40 ns 存储器需要 160 个 4Ghz 时钟。
可以说,芯片可以对指令进行解码,并将执行该指令所需了解的所有信息存储在缓存中(现代英特尔 CPU 为复杂指令执行了大部分此操作)。这意味着第一次遇到复杂指令可能需要数十个周期来解码,而再次遇到时可能需要一个时钟(“在解码的指令缓存中查找”),这经常发生(考虑循环)。好消息是平均指令解码时间非常短。坏消息是,您无法准确估计一条指令需要多长时间才能解码和运行,因为这取决于涉及多少优化和缓存,缓存是否因特定指令执行而命中,以及其他哪些指令由于数据依赖性,仍在处理并优先访问资源。
实际上,晶体管仍然(大量但)供应有限,因此指令解码器无法缓存所有内容。设计师们仍在权衡取舍。一个关键的权衡是“简单”(RISC)指令(往往被执行很多)分配了大量资源,使它们能够在每次遇到时快速解码,而复杂指令(往往执行较少)得到更少硬件资源扔给他们。
具体到解码寄存器访问需要多长时间的问题:很明显,访问寄存器首先需要您知道要访问哪个寄存器,即使它在芯片上。所以读完指令后,需要一些时间来提取寄存器字段。如果您认为芯片上的最少时间是以时钟为单位测量的,那么获得该字段需要的时间不止零,而且至少需要 1 个时钟。真正激进的硬件可能会在单个时钟周期内执行多个操作,因此实际上可以设计解码寄存器的 CPU,并且获取指定寄存器的时间少于一个时钟。一些现代 Intel 处理器只需一步即可解码成对指令,例如“compare; jmp conditional”。
从您的角度来看,这意味着平均而言,指令往往执行得相当快。对非缓存位置的内存访问会造成伤害。
我的一阶 CPU 模型是它们的速度无限快,您所要做的就是担心内存访问。这意味着我倾向于用寄存器中的计算(速度很快)来换取内存访问时间。压缩你的数据结构,它没有坏处:-}