Fab*_*abi 2 assembly avr cpu-architecture micro-architecture
根据 AVR 微控制器的数据表以及 AVR 架构的指令集数据表,某些指令,例如ADD,可以在仅 1 个时钟转换到 ALU 期间获取存储在 GP 寄存器中的 2 个操作数。指令的指令字ADD包括 2 个 GP 寄存器地址;每个 5 位宽,一个用于目标/源,一个用于源。但是这是如何在硬件级别上实现的呢?当他们试图通过相同的直接寻址总线访问 GP 寄存器时,2 个寄存器的 5 位不会相互干扰吗?
多端口寄存器文件广泛用于 CPU 设计。 正如维基百科所说:
现代基于集成电路的寄存器文件通常通过具有多个端口的快速静态 RAM 来实现。
快速谷歌搜索找到了一些幻灯片,其中包含有关多端口 SRAM 单元的一些门/晶体管级详细信息,以及如何从中构建寄存器文件的框图。
这并不是 AVR 独有的。流水线 RISC CPU 通常设计为在没有任何停顿时每个时钟执行(至少)1 条指令,寄存器文件处理每个周期 2 次读取 + 1 次写入。例如 MIPS 和其他经典的 5 级 RISC 流水线。AVR 只是这些想法的 8 位版本。
@Margaret Bloom 指出多端口寄存器文件并不是唯一的实现策略。鉴于 AVR 的时钟速度较慢,寄存器文件可以是单端口的,并且时钟速度更快。
现代超标量 CPU 具有更宽的寄存器文件。
例如,(https://www.agner.org/optimize/blog/read.php?i=857 ) Intel Skylake 可以维持每个时钟周期读取至少 7 个 GP 整数寄存器的吞吐量,同时在同一个时钟周期内写入 3 个寄存器。(并且写入 FLAGS 3 次,这要归功于寄存器重命名打破了 WAW(写后写)危险。虽然这并不真正算作单独的;产生寄存器和 FLAGS 输出的 uops 可以使用相同的物理寄存器条目来两者都持有。RAT 会跟踪什么来自哪里。)
(在现代英特尔上,不同的循环可以轻松地每个时钟周期写入 4 个寄存器;我链接的实验主要是测试每个时钟可以获得多少寄存器读取,以及未融合域的 uop 吞吐量。)