简单的 5 级处理器的各个级需要多少个时钟周期?

cur*_*rge 2 cpu-architecture pipelining cpu-cache risc

5 级流水线 CPU 具有以下阶段顺序:

\n
    \n
  • IF \xe2\x80\x93 从指令存储器中获取指令。

    \n
  • \n
  • RD \xe2\x80\x93 指令译码和寄存器读取。

    \n
  • \n
  • EX \xe2\x80\x93 执行:ALU 运算,用于数据和地址计算。

    \n
  • \n
  • MA \xe2\x80\x93 数据存储器访问 \xe2\x80\x93 用于写访问,使用 RD 状态下的寄存器读取。

    \n
  • \n
  • WB \xe2\x80\x93 寄存器写回。

    \n
  • \n
\n

现在我知道,例如,指令提取是从内存中获取的,这可能需要 4 个周期(L1 缓存)或最多约 150 个周期(RAM)。但是,在每个流水线图中,我都会看到类似的内容其中每个阶段都分配一个周期。

\n

现在,我当然知道真正的处理器具有超过 19 个阶段的复杂管道,并且每种架构都是不同的。但是,我在这里错过了什么吗?如果在 IF 和 MA 中进行内存访问,那么这个 5 级流水线是否需要几十个周期?

\n

Pet*_*des 6

经典的 5 级 RISC 管道围绕单周期延迟 L1d / L1i 进行设计,允许代码中存在 1 个 IPC(每个时钟指令),而不会发生缓存未命中或其他停顿。即希望是常见/好的案例。每个阶段的最坏情况关键路径延迟必须为 1 个周期,否则会触发停顿。

当时的时钟速度较低(甚至相对于 1 个门延迟),因此您可以在一个周期内完成更多工作,并且缓存更简单,通常是 8k 直接映射、单端口,有时甚至是虚拟标记 (VIVT),因此 TLB 查找不是访问延迟的一部分。
第一代 MIPS R2000(和R3000 )具有用于直接映射PIPT分离 L1i/L1d 直写式缓存的片上控制器1 ,但实际的标签+数据位于片外,从 4K 到 64K。通过此设置实现所需的单周期延迟,使用可用的 SRAM 技术将时钟速度限制为 15 MHz (R2000) 或 33 MHz (R3000)。TLB 完全位于片上。

使用 32kiB 8 路 VIPT L1d/L1i 高速缓存的现代 Intel/AMD相比,L1d 至少有 2 个读取 + 1 个写入端口,在如此高的时钟速度下,访问延迟在 Intel SnB 系列上最好情况下 4 个周期,或者5 个周期,包括地址生成。现代 CPU 也具有更大的 TLB,这也会增加延迟。当无序执行和/或其他技术通常可以隐藏延迟时,这是可以接受的,但经典的 5 级 RISC 只有一个管道,而不是单独的管道内存访问。另请参阅x86 上 L1 缓存命中与寄存器的周期/成本?有关现代超标量乱序执行 x86 CPU 的性能与经典 RISC CPU 有何不同的更多链接。

如果您想提高时钟速度以获得相同的晶体管性能(门延迟),您可以将取指和内存阶段划分为多个流水线阶段(即更密集地流水线化它们),如果缓存访问甚至位于关键路径上(即如果缓存访问无法再在一个时钟周期内完成)。延长管道的缺点是增加分支延迟(错误预测的成本,以及正确预测必须隐藏的延迟量),以及增加晶体管总成本。


请注意,经典 RISC 管道在 EX 阶段进行地址生成,使用 ALU 来计算寄存器 + 立即数,这是围绕此类管道构建的大多数 RISC ISA 支持的唯一寻址模式。因此,由于转发回 EX 的加载延迟,对于指针追踪来说,加载使用延迟实际上是 2 个周期。)


如果发生缓存未命中整个管道就会停止:那些早期的管道缺乏负载记分板,无法允许从 L1d 缓存加载命中未命中或未命中未命中的情况。

MIPS R2000 确实有一个 4 条目存储缓冲区,用于将执行与高速缓存未命中存储分离。(根据维基百科,显然是由 4 个独立的 R2020 写入缓冲芯片构建的。)LSI 数据表表示,写入缓冲芯片是可选的,但使用直写式缓存,每个存储都必须进入 DRAM,并且会在没有写入的情况下创建停顿缓冲。大多数现代 CPU 使用回写式缓存,允许对同一行进行多次写入,而不会产生 DRAM 流量。

另请记住,对于 MIPS R2000 等早期 CPU,CPU 速度相对于内存而言并不高,并且单核机器不需要内核和内存控制器之间的互连。(尽管他们可能确实有一个前端总线连接到单独芯片上的内存控制器,即“北桥”。)但无论如何,当时 DRAM 的缓存未命中所花费的核心时钟周期要少得多。每次失误时完全停止是很糟糕的,但它不像现代 CPU 那样可以在 150 到 350 个周期范围内 (70 ns * 5 GHz)。DRAM 延迟的改善程度远不及带宽和 CPU 时钟的改善程度。另请参见http://www.lighterra.com/papers/modernmicroprocessors/,其中有一个“内存墙”部分,以及为什么在大多数处理器中L1缓存的大小小于L2缓存的大小?回复:随着 CPU 速度和内存延迟之间的不匹配不断加剧,为什么现代 CPU 需要多级缓存。

后来的CPU通过执行诸如允许在无故障加载(成功的TLB查找)之后继续执行之类的事情来逐渐允许更多的内存级并行性,只有当您实际读取加载最后写入的寄存器时才停止,如果加载结果是还没准备好。这允许在仍然很短且相当简单的有序管道上隐藏加载延迟,并使用一定数量的加载缓冲区来跟踪未完成的加载。通过寄存器重命名 + OoO exec,ROB 大小基本上是您可以隐藏缓存未命中延迟的“窗口”: https: //blog.stuffedcow.net/2013/05/measuring-rob-capacity/

现代 x86 CPU 甚至在前端的管道阶段之间有缓冲区,以隐藏或部分吸收读取气泡(由 L1i 未命中、解码停顿、低密度代码引起,例如跳转到另一个跳转,甚至只是无法预测简单的始终采用的分支。即仅在获取正确路径以外的内容后,仅在最终解码时检测它。是的,即使像无条件分支也需要对获取阶段jmp foo 进行一些预测。)

https://www.realworldtech.com/haswell-cpu/2/有一些很好的图表。当然,Intel SnB 系列和 AMD Zen 系列使用解码的 uop 缓存,因为 x86 机器代码很难并行解码,因此它们通常可以绕过一些前端复杂性,从而有效缩短管道。(wikichip 有Zen 2 的框图和微架构详细信息。)

另请参阅现代微处理器 90 分钟指南!回复:现代 CPU 和“内存墙”:DRAM延迟和核心时钟周期时间之间日益不匹配。近年来,随着带宽持续大幅攀升,DRAM 延迟仅下降了一点点(绝对纳秒)。

脚注 1:MIPS R2000 缓存详细信息:

R2000 数据表显示D 缓存是直写式的,以及其他各种有趣的事情。

根据 1992 年 SGI 工程师的 usenet 消息,控制逻辑仅发送 18 个索引位,接收一个数据字 + 8 个标签位来确定是否命中。CPU 不关心高速缓存的大小;将正确数量的索引线连接到 SRAM 地址线。(所以我猜行大小是一个 4 字节字?)

您必须使用至少 10 个索引位,因为标记只有 20 位宽,并且您需要标记+索引+2(字中字节)为 32,即物理地址空间大小。这将最小缓存大小设置为 4K。

每 32 位数据使用 20 位标签,效率非常低。对于更大的高速缓存,实际上需要更少的标记位,因为更多的地址被用作索引的一部分。但 Paul Ries 发帖称,R2000/R3000 不支持比较较少的标签位。我不知道你是否可以将一些地址输出线连接到标签输入线,以生成匹配的位而不是将它们存储在 SRAM 中。

32 字节缓存线仍然只需要 20 位标签(最多),但每 8 个字将有一个标签,标签开销提高了 8 倍。具有较大缓存(尤其是 L2 缓存)的 CPU 肯定会希望使用较大的行大小。

但是,您可能更有可能因较少的较大行而发生冲突未命中,尤其是在直接映射缓存的情况下。当您遇到另一次未命中时,内存总线仍然可能忙于填充前一行,即使您有关键字优先/提前重启,因此如果内存总线一开始是空闲的,则未命中延迟并不会更糟。


归档时间:

查看次数:

2436 次

最近记录:

3 年,5 月 前