2023年4月9日 clamchowder

目录

框图

前端: 分支预测

方向预测

分支预测器的速度

间接分支预测

返回预测

前端: 指令获取

重命名器

乱序执行

整数执行

矢量和浮点执行

地址生成

加载/存储单元

地址转换

缓存和内存访问

L1D 缓存

L2 缓存

L3 缓存

DRAM 访问

最后要说的是

参考文献


我们在 Chips and Cheese 已经报道了两个中国的 CPU 架构:在 KX-6000 系列 CPU 中发现兆芯的兼容 X86 的陆家嘴架构,还有,在 D2000 系列 CPU 中发现飞腾的兼容 ARM 的 FT663 架构。兆芯公司成立于 2013 年,是威盛和上海市政府的合资企业。飞腾成立于 2014 年,似乎在其 FTC663 中使用了 Cortex A72 衍生的架构。因此,两者都是中国国内微处理器发展中相对较新的努力。

在这篇文章中,我们将介绍龙芯的 3A5000,这是中国国产架构中的最新产品。3A5000 的 LA464 架构可以追溯到 GS464 内核,它是在第十个五年计划中发展起来的。该计划通过 863 计划等资助国内微处理器工作。在 GS464 的大部分时间里,中国科学院计算技术研究所(ICT)进行了开发。ICT 的历史非常悠久,可以追溯到 1956 年,并处理了许多具有国家重要性的项目,如超级计算机建设和培训计算机研究人员。

多年来,GS464 经历了许多改进。第11个五年计划旨在获得性能更高的中国国产 CPU 和 DSP,并启动了核高基项目。ICT 通过大幅增加结构尺寸来应对,尽管该核心继续被称为 GS464。在第11个五年计划结束时,该核心被移交给新成立的龙芯中科技术有限公司。然而,至少有一些相同的人继续从事GS464 处理器生产线的工作,因为相同的名字出现在随后的研究出版物上(如胡伟武,或 Weiwu Hu)。

摘自 在 Hot Chips 22 上 GS464V 的演讲

这为“十二五”规划奠定了基础,该规划旨在促进“中国国产CPU和DSP的应用 ”。在这些目标下,龙芯生产了一个辐射加固的100兆赫 CPU,被用于北斗卫星。当然,通用的 CPU 也在菜单上。到目前为止,GS464 的分支预测和内存性能都很差。为了应对这一问题,龙芯开始开发 GS464E 架构,该架构基于 IBM 的 POWER 7、英特尔的 Ivy Bridge 和 ARM 的 Cortex A9 的研究。 ​GS464E 似乎构成了我们今天在 3A5000 中看到的 LA464 内核的基础。

3A5000 的 LA464 内核从 MIPS 转移到龙芯的内部架构,被称为 LoongISA 或 LoongArch。今天,龙芯希望 3A5000 能针对从个人电脑到服务器到嵌入式应用的所有领域。我们将深入了解该架构,看看它是如何努力实现这一承诺的。当然,我们也将把它与一些 AMD、ARM 和英特尔的架构进行比较。

我们的许多微观基准测试都依赖于汇编代码。编译器往往会做一些不可预测的、复杂的事情,这使得我们很难从高水平的代码中观察到架构特性。不幸的是,这意味着我们不得不写大量的代码来研究龙芯的 3A5000。编写汇编是很难的,而为一个不熟悉的 ISA(LoongArch64)编写汇编则将难度提高到另一个层次。测试微基准代码也不容易。通常情况下,我们可以通过在具有已知特性的 CPU 上运行测试来验证,并确保结果是理智的。但是龙芯的 3A5000 是我们唯一的 LoongArch64 CPU,而且大多数细节都没有公开。出错的几率很高,所以在整个文章中要记住这一点。

框图

LA464 是一个4发射乱序结构,具有适度大小的缓冲器。在某些地方,它具有现代的功能,如物理寄存器文件和宽矢量执行。但这并不适用所有地方。总的来说,它是一个非常独特的架构,具有我们在其他内核中没有看到的设计决定。

前端: 分支预测

一个 CPU 的流水线从分支预测器开始,它决定从哪里获取指令。分支预测器的性能对于实现高性能是绝对关键的。将流水线送入错误的路径会造成工作的浪费,而花太长时间来确定一个获取目标可能会使流水线饿死。3A5000 上的分支预测精度似乎相当不错,能够在 7-Zip 中与 Zen 1 和 Ampere Altra 抗衡。它在 libx264 中有点落后,但也不至于太差。

方向预测

GS464E 使用锦标赛式的预测器,其中元预测器选择使用本地历史或全局历史进行预测。对于不熟悉的人来说,本地历史指的是之前是否有分支,而全局历史指的是指令流中之前的分支是否被占用。本地历史表、全局历史表和选择表在 GS464E 上都有 16384 个条目,与 DEC 的 Alpha 21264 中实现的经典锦标赛预测器相比,它显得相当庞大。AMD 的推土机也使用锦标赛预测器,而 AMD 的优化指南暗示推土机微架构的全局历史表也有 16384 个条目。

LA464 可能使用了一个类似的预测器。如果我们测试分支预测器在越来越长的随机模式下的表现如何,龙芯的表现平平。它远远达不到目前英特尔和 AMD 的 CPU 的能力。最近的英特尔和 AMD CPU 使用了 TAGE(Tagged Geometric History Branch Predictor,标签化几何历史分支预测器) 或感知器预测器,它们可以用更少的预测器存储量达到更高的准确性。

如果没有相同口径的分支预测,龙芯将很难在更大的核心下获得良好的性能扩展。如果你不得不扔掉不正确的指令,那么更大的内核缓冲区来保持更多的工作,也不会有什么帮助。AMD 推土机微架构或龙芯的预测器可能足以满足一个有 128 个 ROB 项的内核,但时代在进步,龙芯需要更好的东西来保持步伐。

分支预测器的速度

分支预测器的最终目标是加快分支处理速度。预测分支的去向当然很重要,但快速预测也同样重要。如果你的分支预测器需要太长的时间来引导前端,你可能会导致管道中的指令被饿死。为了加快速度,龙芯有一个 64 条 BTB(Branch Target Buffer 分支目标缓冲区,一个分支目标的缓存)。如果一个分支目标从这个 BTB 中出来,前端根本就不用停滞。

如果分支脚印从 64 个条目的 BTB 中溢出,CPU 必须等待分支从 L1i 中被取走,然后计算目标地址。在这一点上,所采取的分支延迟基本上是 L1i 延迟,这在 LA464 上似乎是三个周期。作为比较,最近的英特尔和 AMD 的 CPU 即使在交出数千个分支时也只有一到两个周期的延迟。这种延迟尤其令人痛苦,因为 3A5000 的时钟比 AMD 或英特尔的芯片低得多,所以实际时间的分支延迟相当高。

龙芯的方案避免了大型 L2 BTB 的面积成本,但阻止了分支预测器在 L1i 缺失后跟踪指令流。英特尔、AMD 和 ARM 的 CPU 通过使用分支预测器从指令端驱动预取,可以在大代码范围内保持高指令吞吐量。虽然这种技术在 Sandy Bridge 和推土机时代是新技术,但今天它已成为常识,甚至在低功耗架构上也能实现。在龙芯中没有看到它,真像是从过去吹来的一阵风。

间接分支预测

通往多个目标的分支更难,因为分支预测器也要在分支目标之间进行选择。这些棘手的分支也被称为间接分支,因为它们告诉 CPU 跳到寄存器中的一个地址,而不是直接编码目标。对于一个间接分支,3A5000 在遇到惩罚(可能是错误预测)之前可以跟踪大约 24 个目标。我们看到,在 256 个分支和每个分支两个目标的情况下,总共跟踪了约 512 个间接目标,而没有受到明显的惩罚。

这种水平的间接分支处理能力是很好的。这也是相当值得赞赏的,因为面向对象的编程语言倾向于使用间接分支来处理方法调用。但它的能力不如其他最近的CPU。

Neoverse N1 值得一提,因为它也是一个具有适度性能目标的内核。但是 ARM 能够实现间接分支预测的能力,与 Zen 3 和 Golden Cove 的能力相差无几。龙芯则明显落后。

返回预测

返回是间接分支的一种特殊情况,因为它们通常出现在匹配的调用/返回对中。因此,许多 CPU 保留了一个返回地址的堆栈。在调用时,它们将一个地址推到堆栈上。为了预测一个返回,他们从堆栈中弹出一个地址。龙芯为 3A5000 提供了一个 32 个入口的返回堆栈,这对于绝大多数情况来说应该是足够的。这比 GS464E 有明显的改进,GS464E 有一个 16 条目的返回堆栈。

AMD 的 Zen 2 有一个类似大小的返回堆栈,并经常能够实现超过 99% 的返回预测精度。

前端: 指令获取

一旦分支预测器确定了要去的地方,前端就必须把指令带入内核。这就是指令侧高速缓存层次的作用。首先,3A5000 有一个大的 64KB 4 路 L1i。这一点很好,特别是当 AMD 和 Intel 的高端 CPU 都采用较小的 32KB 指令缓存时。

GS464E(前一代)的指令获取管道。LA464 的获取单元可能是类似的。

然而,看起来大的 L1i 是为了缓解龙芯在从 L2 和其他地方获取代码时的不良性能。Zen 1 和 Skylake 在从 L2 提取指令时都能维持 4 的 IPC,即使他们不得不从 L3 运行代码,仍然表现得非常好。龙芯无法与之相提并论,对于较大的代码足迹来说,可能会被前端带宽所限制。

奇怪的是,从 L2 获取的代码带宽比从 L3 获取的要差。我想知道龙芯在实现硬件指令高速缓存一致性时是否遇到了一些困难。如果做得正确,硬件指令缓存一致性可以使 JIT 化的代码受益,并能更好地扩展到高核数。然而,这并不容易。龙芯的 L2 是非包容性的,这意味着它不能作为一个窥探过滤器。也许一个来自指令端的 L2 命中必须探测 L1D,以确保它得到最新的数据。但是,L3 命中可能会受益于位于 L3 复合体中的单独的一致性目录,它可以指示是否可以在没有窥探的情况下提供最新的数据。

重命名器

在指令被获取和解码后,重命名器必须在后端分配资源来跟踪它们。除了显而易见的寄存器重命名以打破虚假的寄存器名称依赖之外,重命名器还可以使用某些技巧来向执行引擎暴露更多的并行性。最近的英特尔和 AMD CPU 可以做到这一点,在重命名器中自由处理寄存器到寄存器的移动和清零习惯。

据我所知,龙芯并没有任何这样的优化。重命名器做了你从计算机科学课程中所期望的事情,而这就是它。

乱序执行

吸收缓存和内存延迟是保持高性能的关键,龙芯有一个规模适中的乱序引擎来做到这一点。就规模和雄心而言,它看起来与 Neoverse N1 的隐约相仿。两者都有一个 128 条目的 ROB,以及类似的寄存器文件大小。N1 有一个分布式调度器,而龙芯使用一个更统一的调度队列配置,总条目更少。

结构 适用于指令... 龙芯 3A5000 (LA464) GS464E** Neoverse N1 Zen 1
重新排序的缓冲区 存在 128 128 128 192
整数寄存器文件 写入标量整数寄存器 ~91 speculative + 32 architectural = ~123 entry 128 120 entry 180 entry
矢量/浮点 寄存器文件 写入浮点/矢量寄存器 ~90 speculative + 32 architectural = ~122 entry
256-bit entries, ~3.9 KB total capacity
128 entry
64-bit,
1 KB total capacity
128 entry
128-bit entries, 2 KB total capacity
160 entry
128-bit, 2.5 KB total capacity
调度器 正在等待执行 32 entry INT
32 entry FP
32 entry memory
16 entry INT
24 entry FP
32 entry memory
16 entry branch
3×16 entry INT
2×16 entry FP
2×12 entry memory
4×14 entry INT
36 entry FP + 64 entry NSQ
2×14 entry memory
加载队列 从内存中读出 64 entry 64 entry? 56 entry 116 entry*
存储队列 写入存储器 44 entry Shared with loads? 44 entry 44 entry
分支顺序缓冲区 影响控制流 26 entry 24 entry 36 entry 136 Not Taken
32 Taken

*Zen 的优化手册说负载队列是 44 个条目,但核心可以保持 116 个负载在飞行。为了保持一致性,使用了测量的 116 的数字

与较早的 GS464E 内核相比,LA464 保持了相同的重排缓冲区和寄存器文件大小,但龙芯加强了最重要的调度器大小。对于具有 128 个 ROB 项的 CPU 来说,GS464E 已经具有相当大的寄存器文件尺寸。LA464 应该能够更好地利用其 128 条 ROB。但最近的 AMD、英特尔,甚至 ARM 的 CPU 都远远领先于龙芯。他们有更大的重排缓冲区,其他结构也得到增加,以保持核心的平衡。

龙芯可能选择了保守的结构尺寸增加,以提高时钟速度。如果要在通过加倍结构尺寸提高 IPC(就像 GS464E 对 GS464 所做的那样)和通过提高时钟速度提高整体性能之间进行选择,后者肯定是更好的选择。然而,西方公司在提高时钟速度的同时也能增加结构尺寸,将龙芯甩在了后面。

整数执行

在前一篇文章中,我们介绍了矢量执行,所以如果你想了解 3A5000 上的 FPU,那么就去读那篇文章。现在是时候看看龙芯 3A5000 的标量整数方面了。与 GS464E 相比,龙芯的 LA464 内核极大地提高了整数吞吐量,有四个 ALU 管道而不是两个。之前的 GS464E 衍生的内核看起来总是有点滑稽,在一个 4 发射的内核里有两个 ALU。公平地说,每个推土机模块中的内核都是4发射的,但只有两个 ALU,但这是一个特殊情况,强调的是共享前端的多线程性能。

虽然龙芯在 GS464E 的基础上进行了大规模的改进,但他们目前的内核在整数执行方面确实有一些不足之处。LA464 每个周期只能解决一个分支,即使该分支没有被采纳。这种能力相当于 ARM 的 Neoverse N1 或英特尔的 Sandy Bridge 能做到的。但是,较新的英特尔和 AMD CPU 可以在每个周期内维持两个分支,通常提供至少一个分支没有被采取。

指令  3A5000 Throughput/Latency GS464E Throughput/Latency Neoverse N1 Throughput/Latency Zen 1 Throughput/Latency
64b Integer Adds 4 per cycle
1 cycle latency
2 per cycle 3 per cycle
1 cycle latency
4 per cycle
1 cycle latency
64b Integer Multiplies 2 per cycle
4 cycle latency
2 per cycle
3 cycle latency
1 per cycle
2 cycle latency
1 per cycle
3 cycle latency
64b Integer Divisions 0.11 per cycle
9 cycle latency
0.05 per cycle
20 cycle latency
0.07 per cycle
8 cycle latency

注意,Neoverse N1并不支持256b指令。

龙芯在整数乘法的吞吐量方面确实有优势。与 Gracemont 一样,3A5000 可以在每个周期做两次标量整数乘法,而其他大多数内核只能做一次。即使 3A5000 的时钟速度很低,但在绝对吞吐量方面,它可以超过 2020 年前的 ARM 和 x86 对手。然而,与最新的 AMD 和英特尔台式机内核相比,这一优势被削弱了,它们的时钟是 3A5000 的两倍多。它被整数乘法延迟进一步削弱,整数乘法延迟为 4 个周期,表现平平。这与 AMD 的 Phenom 和英特尔的 Core 2 相同,这两款产品已经有 20 多年的历史,而且时钟比 3A5000 高。英特尔和 AMD 的任何最新产品都结合了更高的时钟和更低的周期数延迟,使它们领先了很多。

矢量和浮点执行

我们之前研究了 3A5000 的矢量和浮点执行布局,没有发现其能力弱于 Zen 1 和 Skylake。更多细节在那篇文章中。但总结起来,龙芯只有两个矢量执行端口,并受到高 FP 执行延迟的影响。无论矢量宽度如何,浮点加法、乘法和融合乘法-加法指令的执行有五个周期的延迟。这与 AMD 的 RDNA 2 图形架构的延迟相同,这很有趣,因为 RDNA 2 也达到类似的时钟。

矢量整数操作更好,矢量添加的延迟为一个周期。尽管如此,一个四核 Ampere Altra 云计算实例在 libx264 视频编码方面成功地超越了 3A5000,这要归功于更高的时钟速度和可能更广泛的专门指令集的结合。就像标量整数方面一样,3A5000 确实有优势,能够在每个周期进行两次 256 位矢量整数乘法,使其与 Skylake 持平,并超过了 Zen 1。

与英特尔和 AMD 的比较只是故事的一个方面。较早的 GS464E 核心有 64 位 FP 单元,使其回到了 x87 和 MMX 时代。龙芯当然要在他们得到的基础上工作。当 ICT 管理狗剩(Godson)的开发时,他们创造了 GS464V,这是 GS464 的一个变种,具有强大的向量单元,用于超级计算机。我怀疑 GS464V 构成了 LA464 的矢量实现的基础。根据 IEEE 的一篇论文,GS464V “在内核中集成了两个256位的矢量单元”,并且“矢量ALU模块被使用了两次”。

地址生成

存储器操作从地址生成单元开始执行,该单元计算出加载或存储操作要寻址的存储器地址,并将其传递给加载/存储单元。龙芯 3A5000 的 LA464 内核有两个AGU,使其在每个周期内执行两个内存操作。两个都可以是加载,一个可以是存储。这使得它与 Neoverse N1、Zen 1 和 Sandy Bridge 大致相当。

然而,它比英特尔的 Haswell 架构及其后继者落后一步,后者可以在同一周期内进行两次加载和一次存储。当前一代 AMD 和英特尔的 CPU 也有大规模扩展的内存执行能力。例如,Golden Cove 可以在每个周期进行两次加载和两次存储。Zen 4 每个周期可以进行三次内存操作,其中两次可以是存储。当龙芯开发 GS464E 时,考虑到英特尔的 Ivy Bridge,双 AGU 的设置似乎完全没有问题。但时代在进步,现在看来已经相当过时了。

加载/存储单元

一旦虚拟地址被生成,它们就会被传递给加载/存储单元。加载/存储单元确保内存依赖性得到尊重,并将虚拟地址转换为物理地址。为了加快速度,龙芯可以推测地在未知地址的存储之前执行负载。

如果一个负载确实从较早的存储中获取了数据,龙芯可以以 7 个周期的延迟转发存储数据。只要负载包含在存储中,并且访问不跨越 64B 缓存线的边界,存储转发就能发挥作用。对于一个 2.5GHz 的 CPU 来说,7 个周期的存储转发延迟并不是最好的性能。Zen 1 有相同的存储转发延迟,但时钟要高得多,而 Skylake 可以以 5 个周期的延迟转发存储数据(或者,只比无争议的负载延迟多一个周期)。

龙芯的行为有点像 Skylake,因为两者都做了一个粗略的检查。龙芯以 8B 的粒度进行检查,而 Skylake 则以 4B 的粒度进行检查(即,比较一个额外的位)。这意味着,如果负载和存储在龙芯上碰到同一个 8 字节的块,即使它们没有真正重叠,也不能平行进行。这个 8B 的重叠惩罚也适用于 16KB 的页面。如果加载和存储在不同的 16KB 页面内的相同偏移量上触及相同的 8B 块,也会有一个错误的依赖性。最后,如果一个负载部分地与一个存储重叠,龙芯会受到 14 个周期的惩罚。这种失败的存储转发惩罚并不坏,而且与其他 CPU 的情况一致。

如果访问跨越 64B 缓存线,负载/存储单元的工作就会变得更难,因为这将涉及到两个 L1D 访问。这种访问被称为 "错位访问",因为它们跨越了 L1D 对齐边界。龙芯通过在两个周期内执行错误对齐的负载来处理它们。这并不离谱,尽管较新的英特尔和 AMD CPU 根本没有看到任何错位负载的惩罚。存储对龙芯来说要糟糕得多,因为一个错位的存储需要 10 个周期。酷睿 2 时代的老英特尔 CPU 确实遭受了类似的惩罚,但最近的 CPU 通常要好得多。考虑到 CPU 的低时钟,10 个周期的惩罚是相当可观的。

如果一个访问也跨越了 16K 页的边界,除了两次 L1D 访问外,还需要两次 TLB 查找。龙芯对这种情况处理得很好,同样的错位加载惩罚,而错位存储惩罚增加到 15 个时钟。Zen 1 需要 24 个周期的惩罚,如果 Zen 1 以 4GHz 的速度运行,实际时间几乎相同。

地址转换

在生成地址之后,内核必须将虚拟地址(如程序所见)转换为物理地址,与 DRAM 中的位置相对应。这种转换允许操作系统执行权限,并为每个进程提供自己的内存视图,确保一个行为不端的程序不会导致整个系统崩溃。然而,地址转换也会产生开销。TLB 通过记住这些地址转换将这种开销降到最低。

龙芯默认以 16KB 的块,或页来翻译地址。作为比较,X86 和 ARM CPU 通常使用 4KB 的页。龙芯的大页意味着每个 TLB 条目有更多的覆盖范围。LA464 有一个 64 个条目的 L1 DTLB,它可以覆盖 1MB,由一个 2048 个 L2 TLB 支持,总 TLB 覆盖范围为 32MB。这些大的页面大小应该使龙芯比其 x86 和 ARM 的同类产品有一些优势。

撞击 L2 TLB 似乎比撞击 L1 TLB 增加了 2.3ns 的延迟,或大约 5-6 个周期。这与 Zen 1 相比是有利的,后者的 L2 TLB 延迟为 7-8 个周期。然而,Zen 1 的高时钟意味着它享有更好的实际延迟。

缓存和内存访问

一旦加载/存储单元完成了它的检查,它就会从内存层次结构中获得所要求的数据。像许多现代的 CPU 一样,龙芯使用了三层的缓存设置。今天所有的高性能 CPU 都依赖于缓存,因为 DRAM 性能的提高并没有跟上 CPU 核心性能的提高。

L1D 缓存

与以前的 GS464 系列的架构一样,3A5000 享有一个大小适中的 64KB L1D。它是 4 路设置的关联性,以实现虚拟索引,物理标记寻址的 16KB 页面。然而,延迟是一个薄弱点。四个周期可能听起来并不坏,但在 3A5000 的低时钟速度下,我期待着更好的结果。AMD 的 K10 架构在使用旧工艺节点的更高时钟下实现了 3 周期的延迟。

有效的 L1D 延迟变得更糟,因为龙芯和 MIPS 一样,缺乏一个按比例的索引寻址模式。编译器最终产生了额外的指令来计算数组索引的地址,极大地增加了 L1D 的延迟。作为比较,x86-64 和 aarch64 都有一个缩放索引寻址模式。最多,使用这种能力会产生一个周期的惩罚。在龙芯上,GCC 编译的数组索引代码的延迟为 8 个周期,这在 2.5GHz 下是很残酷的。

GS464E(LA464的前身)的 L1D 流水线

在带宽方面,龙芯将 L1D 设置为处理 256 位向量执行的需求。使用未记录的 LASX 指令,我们能够在每个周期内进行两次 256 位的加载,或者一次 256 位的加载和一次 256 位的存储。因此,3A5000 拥有比 Zen 1 更好的 L1D 带宽,即使有 AMD 的时钟速度优势。然而,它无法与 Skylake 相比。

L2 缓存

像今天的许多 CPU 一样,龙芯有一个 L2 中级缓存,使内核与 L3 延迟隔离。在 3A5000 上,L2 是 256KB,16 路设置关联,并作为一个受害者缓存。二级潜伏期一般为 14 个周期。英特尔在过去的十年中一直以 12 个周期的延迟运行 256KB 的二级缓存,并且以更高的时钟启动。如果我们看一下实际的延迟,3A5000 的 5.6 纳秒比 FX-8350 的 4.8 纳秒还差。Zen 1 甚至比这更快,而且仍然有更多的 L2 容量。

L2 带宽平均为每周期 21.3 字节——不是很好,也不可怕。这比 Skylake 每周期超过 28 字节,或 Zen 1 每周期超过 24 字节的情况要差一点。同样,时钟速度的差异意味着 AMD 和英特尔的旧 CPU 比龙芯的 3A5000 有明显的实际二级带宽优势。

L3 缓存

龙芯的 L3 可以说是 CPU 最好的功能之一,因为它为四核集群提供了 16MB 的容量,具有不错的带宽和延时。L3 的功能是作为一个受害者缓存,由四个库构成。根据 3A5000 的用户手册,L3 和内核是通过一个使用 AXI 协议的“5×5分频开关”连接的。CPU 内核作为主站连接到开关,而 L3 缓存片作为从站。开关端口的设置使每个端口每周期有 32 字节的读取带宽,每周期有 16 字节的写入带宽。


3A5000 的互连设置,如参考手册上所述

这种互连设置可能是从 Godson 3 时代延续下来的,当时 ICT 致力于在高核数配置中实现旧的 GS464 内核。这并不令人惊讶,考虑到即使在转到龙芯的所有权之后,同样的人也在为这个项目工作。然而,龙芯已经将每个 L3 片的读取带宽提高了一倍。


Godson-3B1500 的互连设置。在每个四核集群内,高层结构看起来非常相似。

有了四个 L3 片,每个片能够在每个周期提供 32 个字节,我们应该在 2.5GHz 下获得 320GB/s 的理论 L3 带宽。我们没有得到任何接近这个数字的东西。也许内核不能跟踪足够多的未完成的 L2 失误来吸收 L3 延迟。也许在 5×5 交换器中存在争论。也许 3A5000 对 L3 缓存的时钟频率低于核心频率。毕竟,Godson-3B1500 以 1.25GHz 的频率运行核心,但以 1GHz 的频率运行 L3。

无论情况如何,AMD 和英特尔都有明显的 L3 带宽优势。Zen 1 和 Skylake 都可以从 L3 每周期拉出更多的字节,而它们的高时钟速度使龙芯更加落后。龙芯确实有容量上的优势,但在面对 AMD 和英特尔的更多现代芯片时,这种优势消失了。

对龙芯有利的是,至少他们设法实现了一个远比推土机架构好的 L3。我们看到,随着线程数的增加,L3 带宽的扩展大致是线性的。当龙芯的规模超过四核配置时,扩展性应该很好,因为每个 L3 实例都是四核集群的私有资源。像 AMD 的 EPYC 一样,L3 带宽应该随着更多核心集群的增加而线性扩展,除非有某种可怕的错误。

L3 有大约 40 个周期的加载—使用延迟。以周期计算,这还不错,与 Zen 2 相似。 然而,16ns 的绝对延迟对于一个客户端设计来说是相当不引人注目的,对于一个运行在 2.5GHz 的 CPU 来说,龙芯确实应该有一个更短的 L3 管线长度。

龙芯的 3A5000 与之前的 Godson-3B1500 相比确实很好。根据发表在 IEEE 上的一篇论文,Godson 3 的 L3 延迟约为 50 个周期。在 1.25GHz 时,这将是 40 纳秒。16 纳秒是世界上最好的,所以龙芯公司取得的进步应该受到赞扬。

Godson-3B1500 在 1.25 GHz 核心和 1 GHz LLC 时钟下的延迟结果,发表在《32/28 纳米 Bulk CMOS 中的 8 核 MIPS 兼容处理器》,IEEE 2014 年

如果 3A5000 错过了 L3,它通过第二级 AXI 开关访问 DDR4 内存控制器。

DRAM 访问

从上图来看,Godson-3B1500 有 160-170个 周期的内存延迟,相当于 128-136 ns。对于使用 RDIMMs 的双通道 DDR3-1066 配置来说,这还不算太糟糕。不幸的是,对于 3A5000 来说,龙芯在转向 DDR4 时掉了链子。我们使用 DDR4-2666 测量了 144 ns 的内存延迟。龙芯一定是从 wish.com 购买的内存控制器,因为它是一堆燃烧的垃圾。

我们用 DDR4-2666 进行测试,两个插槽都装满了。3A5000 有一个双通道内存控制器,这应该使它的理论带宽与五到六年前的消费芯片相当。“理论上”是这里的关键词,因为现实是不同的。

单个龙芯可以从 DRAM 中获取约 7GB/s 的带宽,而所有四个核心加起来也不过 14GB/s。在一个全核心的工作负载中,每个核心将不得不使用仅 3.37GB/s 的 DRAM 带宽,这使得带宽可能受到限制。对于双通道 DDR4 设置来说,这是一个糟糕的性能,因为它甚至远远落后于平庸的 DDR3 配置。例如,采用双通道 DDR3-1333 的 i7-4770 的速度刚刚超过 19GB/s。

获得便宜的内存控制器的后果会有所不同。像网页浏览或文字处理这样的日常任务可能没有问题。服务器程序、HPC工作负载、图像处理、视频编辑和并行代码编译可能就不行了。

我们还应该记住,这是一个运行在 2.5GHz 的四核芯片。当龙芯试图追求更高的时钟速度或更高的核心数量时,内存性能将成为一个越来越严重的问题,因为计算与带宽之比将变得更加糟糕。这在延迟方面也适用。144.5 ns 在 2.5 GHz 时是 361 个周期,但在 4 GHz时是 578 个周期。在某种程度上,3A5000 的非常低的时钟速度掩盖了其最糟糕的内存性能问题。

最后要说的是

龙芯的 3A5000 是我们迄今为止看到的最有希望的中国国产 CPU。与兆芯 KX-6640MA 和 飞腾 D2000 相比,龙芯的 3A5000 是一个宽核,具有更好的平衡后端和更好的缓存层次。但它在追求成为通用 CPU 的过程中,遭遇了与其他两款相同的基本问题。龙芯的 LA464 根本无法提供与任何近期英特尔或 AMD 架构相同的性能。与西方同类产品相比,LA464 的架构更小,L2 和 L3 缓存更差,DDR4 内存控制器也令人尴尬。即使龙芯把他们的核心从 1GHz 提高到 2.5GHz,也没有人在这么低的时钟下运行台式机甚至笔记本 CPU。由于其巨大的时钟速度缺陷,龙芯甚至无法达到与最近的台式 CPU 相同的性能标准。它甚至在与运行在 3GHz 的 Neoverse N1 的对抗中挣扎。

来自 “中国的 CPU 和 DSP 设计介绍”。所有列出的 GS464E“关键参数”在 LA464 上都是相同的。

龙芯的进展也不容乐观。从微观基准测试来看,LA464 的架构基本上比 GS464E——2010 年代初的核心——多出一代。GS464E 的设计是为了在时钟对时钟的性能上接近于那个时候的西方核心。这是一个巨大的问题,因为即使在那时,Sandy Bridge 和推土机微架构的时钟也明显高于今天的 LA464。当然,Golden Cove 和 Zen 4 也比 Sandy Bridge 领先很多很多代。

其结果是,今天,龙芯并没有感觉到比十年前更接近英特尔和 AMD。我也不认为他们有很好的机会在相同的性能范围内着陆,除非他们做出一些巨大的飞跃。制作一个性能合格的低功耗处理器比制作一个领先的 CPU 要容易得多。追求高性能意味着要解决一个又一个的瓶颈问题,而解决这些瓶颈问题会随着你挑战 CPU 性能的极限而变得越来越复杂。

软件生态系统是另一个问题。具有讽刺意味的是,3A5000 的 ISA 将使它在实践中不那么可用,尽管它比飞腾或兆芯强。龙芯指出,MIPS 受到薄弱的应用支持和不如 x86 强大的工具链的影响。创造一个新的、不兼容的指令集,大部分重复使用 MIPS 的工具链,是一个不解决这个问题的搞笑的愚蠢方式。为了增加这个问题,龙芯将 LoongArch ABI 分成了“旧世界”和“新世界”,这两个世界是互不兼容的。这只是给这个混乱的软件生态系统增加了另一个愚蠢的层次。

从 2022-07-18 起,所有社区发行版与所有商业的 LoongArch 发行版都不兼容。所有建立在社区发行版上的二进制软件,以及一些用高级语言编写并以源代码或字节码等形式存在的软件(如用 Python 或 Java 编写的软件)不能在商业发行版上运行,反之亦然。所有来自 ISV 的闭源软件,如 WPS Office,都是建立在商业发行版上的,所以它们极不可能在社区发行版上原样运行。

这就是所谓的新世界和旧世界之间的兼容性问题。因为龙芯公司在向开源社区宣布 LoongArch 之前完成了所有的商业行动,所以开源的 LoongArch 生态系统是新世界;与此相反,所有的商业发行版和相关的生态系统构成了旧世界。这两个世界最终要统一起来,但目前是两个平行的宇宙;而要使这两个世界相互兼容,其技术难度是巨大的。
https://blog.xen0n.name/en/posts/tinkering/loongarch-faq/#why-cant-i-run-closed-source-software-like-wps-office-on-community-distributions-aka-whats-this-so-called-old-world-and-new-world

龙芯确实有 ISA 扩展来帮助 ARM、MIPS 和 x86 的二进制翻译。但这是一个相当复杂的工作方式,首先没有使用一个更通用的 ISA。我们在 Loongnix(一个基于 Debian 的 Loongson 发行版)上的二进制翻译也没有什么乐趣。最大限度地减少二进制翻译带来的性能损失是很酷的,但不工作就不酷了。平心而论,32 位 x86 版本在二进制转换下确实可以工作。但现在有大量的程序是 64 位的,你真的需要 x86-64 翻译来工作。即使它真的能工作,二进制翻译也会给已经很低的 CPU 增加开销。

最后,龙芯的 LA464 是一个有趣的低功率、低性能架构的例子。龙芯/计算所团队肯定一直在努力工作,试图实现为他们设定的目标。但是他们的创新速度落后于 AMD 和英特尔,这两家公司一直在不懈地推动 CPU 性能的发展。但是看看 LA464,然后再看看 Zen 4 或 Golden Cove,就可以看到 AMD 和英特尔在推动 CPU 性能的边界方面是多么令人印象深刻。它还显示了西方公司的持续进步如何给中国的 CPU 制造商提供了一个非常困难的移动目标。

如果你喜欢我们的文章和新闻报道,并且你想支持我们的努力,那么请考虑前往我们的 Patreon 或 PayPal,如果你想给我们扔几块钱。如果你想与 "薯片和奶酪 "的工作人员和幕后人员交谈,那么可以考虑加入我们的 Discord。

参考文献

1、胡伟武等人,32/28 纳米块状 CMOS 中的 8 核 MIPS 兼容处理器,IEEE 固态电路杂志,第49卷,第1号,2014年1月
2、胡伟武等人,Godson-2 处理器的微架构
3、胡伟武等,Godson-3:具有 x86 仿真的可扩展多核 RISC 处理器,IEEE Micro,2019年12月
4、胡伟武、张一夫、傅杰,中国 CPU 和 DSP 设计简介,《中国科学报》信息科学版,2015年10月

原文:Loongson’s 3A5000: China’s Best Shot? – Chips and Cheese

龙芯的3A5000:中国的最佳拍档?相关推荐

  1. 龙芯3A5000初样顺利交付流片

    此前,龙芯完成3A5000设计初样的流片交付.在3A4000架构的基础上,3A5000采用12纳米工艺,设计频率提高近40%,同频模式下功耗降低近60%,同时保持与3A4000芯片管脚兼容. 龙芯3A ...

  2. 关于龙芯的争吵我都无语了

    2019独角兽企业重金招聘Python工程师标准>>> 和很多国人一样,龙芯一出世就让俺振奋并一直关注.不过出了汉芯那破事,很多人对国产CPU一直报怀疑态度.可是后来本本都出来了,并 ...

  3. 龙芯负责人李国杰披露中美CPU暗战内幕

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 龙芯负责 ...

  4. 龙芯3a5000相当于英特尔什么水平

    龙芯3a5000相当于英特尔i5-7200u, 龙芯3A5000它的主频是2.3GHz到2.5GHz,设计核心是4核心,工艺技术是12nm. 龙芯3a5000性能怎么样这些点很重要 http://ww ...

  5. 龙芯3号_中国芯崛起!新一代龙芯3号发布,国产CPU有望比肩世界先进水平

    原标题:中国芯崛起!新一代龙芯3号发布,国产CPU有望比肩世界先进水平 天下网商记者 黄天然 "中国芯"又获重大突破. 12月24日,龙芯中科发布了自主研发的新一代通用处理器(CP ...

  6. 龙芯3a5000下安装达梦8和Qt

    一.DM8安装 龙芯3a5000+kylin10 1.创建用户和组 #创建安装用户和用户组 sudo groupadd dm sudo useradd -g dm -m -d /home/dmdba ...

  7. 百度飞桨与龙芯3A5000完成兼容性互认证,助力国产CPU人工智能应用创新

    百度飞桨和龙芯中科 完成兼容性互认证 近日,百度飞桨深度学习框架与龙芯3A5000完成适配,百度飞桨深度学习框架V2.1在龙芯3A5000环境上可以顺利安装,且系统整体运行稳定,满足用户的关键性应用需 ...

  8. 龙芯3A5000完成流片 同主频性能追平AMD Zen1

    前不久,龙芯3A5000完成流片,该CPU基于龙芯自主定义指令集LoongArch.据小道消息,SPEC06测试定点26分(base  @2.5Ghz).这个成绩已经达到预期指标,而且经过进一步优化, ...

  9. 龙芯2h芯片不能进入pmon_“龙芯”18年:这个团队,终结了中国计算机产业的“无芯”历史...

    近期在第二届数字中国建设峰会上展出的国产芯片龙芯3号. 芯片是信息产业的灵魂,通用CPU(中央处理器)可以说是芯片中的"珠峰".自主研发CPU,难度很大. 在这个故事的起点,200 ...

最新文章

  1. python随机生成30个8_Python生成六万个随机,唯一的8位数字和数字组成的随机字符串实例...
  2. 求二叉树中叶子结点的个数
  3. 行内元素和块状元素一览表
  4. python线程暂停_关于多线程:如何使“停止”按钮终止已经在Tkinter中运行的“开始”功能(Python)...
  5. 在php中使用mb_substr($row['title'],0,15,'utf-8')解决获取的字符后面几们的乱码问题
  6. 凡子谷机器人创客教育_【活动纪实】机器人创客教育课堂——液压升降台
  7. Visual Studio 2010中的UML
  8. php.ini路径设置、libmysql.dll加载等
  9. scala 函数中嵌套函数_Scala函数–声明,定义,调用和嵌套函数
  10. 如何设计一个本地缓存,涨姿势了!
  11. hdu 1506:Largest Rectangle in a Histogram 【单调栈】
  12. thinkphp mysql 原生_第七节:thinkphp6数据库设计和原生查询
  13. Java下载base64图片
  14. Microsoft Word 教程:如何在 Word 中插入图片、图标?
  15. 笔记本打开计算机不显示摄像头,笔记本电脑摄像头没有图像怎么回事_笔记本摄像头提示没有图像设备如何处理-win7之家...
  16. 坚果云同步linux,备份Linux系统数据到坚果云
  17. 下一步工作应该怎样开展
  18. 周末加班,中午吃饭时看到了马总的一条新闻
  19. 解决虚拟机IP地址无法获取和网络无法连接
  20. 网线 绿灯长亮 黄灯不亮

热门文章

  1. 【第181期】恭喜KKasier入职游戏策划:主策和制作人有啥区别
  2. 数学建模学习(17):图与网络模型之图详细讲解,最直白的话讲数据结构,内容偏多,建议先收藏
  3. WorkFlow工程项目简介
  4. Bilateral Filters(双边滤波算法)原理及实现(一)
  5. 双边滤波(bilateral filter)以及联合双边滤波(joint bilateral filter)
  6. Google Earth Engine(GEE)——影像导出谷歌硬盘发生错误Error: Exported bands must have compatible data types
  7. C11编译 systemc 2.3.3 和 SCV 2.0.1
  8. Javascript基本内容
  9. String s=new String(xback)和String s=xback的区别?
  10. 使用Ubuntu 20.0.4编译Elasticfusion