今天小编分享的科技经验:AI时代进击的CPU们,欢迎阅读。
毫无疑问,GPU 和 AI 加速器才是 AI 时代算力的最大提供者。训练 AI 模型需要 GPU 的超大算力,但一块 GPU 越来越存不下今天的模型,互联多块 GPU 成了刚需,各种高端的网卡,DPU 也诞生了。推理 AI 模型也需要非常高的算力,同时对存储带宽的要求也越来越高。即便是端侧,这几年移动 GPU 和 NPU 的进步,AI 的部署也大多从 CPU 侧迁移到更大算力,更高能效的模块中。一切都在向着异构 + 专有结构的方向发展。
CPU 这个曾经的通用计算王者现在面临很尴尬的处境:往往沦为大型 AI 负载的调度器和数据搬运工具,还要承担加速器处理不了的长尾需求,被吐槽拖慢了整体速度。然而各家 CPU 厂商总要生存,他们近几年也陆陆续续在自家 CPU 上引入 AI 的加速功能,以期能在这个言必称 AI 的市场里获得机会。算力密度上的天生弱势,导致 CPU 厂商更多在推理侧发力。
AI 运算的二八法则
还好 AI 的计算规律也符合二八法则:从深度神经网络开始流行,到现在的大语言模型,最大的计算模块基本就是卷积,矩阵乘法一类的计算密集型操作,它们在绝大多数 AI 模型中大约能占据八成的计算规模,剩下几十到上千种算子占据二成左右。
深度学习中的卷积运算,可以转换成矩阵乘法的模式进行计算,如下面两篇文章展示:M1 Max 初相遇,快快乐乐写卷积," 远超 " 理论浮点峰值。
矩阵乘法是由乘法和加法这两种基本运算所组成,且成对儿出现。我们假设相乘的两个矩阵分别是 × 维的(记作 ×),以及 × 维的 (记作 ×),结果矩阵就是 × 维矩阵 (记作 ×)。那么矩阵乘法的操作就是:×+=×××。这个计算过程包含了 ×× 次乘法,和同样数量的加法。所以高性能计算和 AI 里统计矩阵乘法的运算次数就是乘法和加法的总次数:2××× ,用这个数字除以矩阵乘法的计算时间,就可以得到我们通常表示算力大小的 FLOPS。如果这个值高于 109 ,就可以表示成 GFLOPS;如果高于 1012 ,就可以表示成 TFLOPS... 这个指标就是计算矩阵乘法或者卷积等 AI 核心操作的绝对性能指标。
人们习惯于把复杂的问题拆成简单的步骤组合,或者庞大的任务拆成很多粒度更小的任务组合。矩阵乘法或者卷积运算,往往就是拆成多种粒度的分块的矩阵乘法,最终分解到硬體的计算单元上去执行并行计算。以 nvidia 为代表的 GPU 架构,最早在 17 年加入了 TensorCore 这种矩阵乘法指令,相比早先的多核单元内 SIMT 运算,直接提升了一个数量级的性能;多数 AI 加速器也是以某种形式的 Matrix 结构作为主要的计算单元(例如脉动阵列),支持卷积和矩阵乘法类的运算,也能取得很优秀的性能。唯独 CPU,因为功能定位通用多元,芯片设计复杂以及尽量不破坏传统体系结构的原因,早年一直通过对 SIMD 向量指令的扩展来支持这些算子,直到最近两年才开始加入类似 Matrix 结构的专用 DSA。
本文也从这个角度简单回顾下各家 CPU 厂商的 AI 能力构建历史。
x86:成也生态,败也生态
即便 2023 年,nvidia 的营收也才突破 600 亿美元,intel 年年 600 亿美元,市值仅有 nvidia 的零头,AMD 的一半 ... 事实上,intel 这 10 年来也一直在不停地加大对 AI 的投入:Xeon Phi,Nevana Sys,Movidius,Altera FPGA,Habana 以及自研架构的 GPU。但这些似乎都不那么成功,往往难产,最终被砍掉;或者推迟,等真正发布的时候已经不见优势。
所以这十年来,intel 的战略就是通过 Xeon 伺服器 CPU 去和 GPU 打,在 x86 里面塞入了大量的重型负载。比如 AVX512 指令集,就是为对抗 GPU 的高性能计算能力诞生的。这个指令集十分的庞大,除了将前面所有的指令集更新到 512 位以外,还加入了大量新的特性,尤其是 AI。
下面通过四个部分介绍下 intel 对于 x86 的 AI 能力构建的历史过程:
基本的单精度浮点向量运算
CPU 最早是通过单精度的向量指令的方式去拼凑出整个矩阵乘法的操作。无论是训练还是推理,32 位单精度浮点操作都足够用。
早年的 SSE 指令支持 128 位的单精度向量乘法和向量加法,也就是一条指令只能执行 4 个 float 类型的乘法,或者加法,指令算力密度很低;AVX 指令的引入,增加到 256 位,算是提升了一倍;因为矩阵乘法,卷积,FFT 这些操作,乘法和加法总是成对出现,所以 AVX2 增加了乘加指令,相当于一条指令执行了 +=× ,绑定了成对的乘法和加法,将单指令算力密度再提升一倍;最后就是 AVX512F 指令的引入,将乘加指令延长至 512 位。从 SSE 到 AVX512F,单一指令的计算密度提升到了 8 倍。指令操作如下图所示:
从 SSE 到 AVX512F 四种单精度向量乘加指令
按照关于 sgemm_hsw 的一点解释说明,x86 使用 AVX/FMA 指令实现寄存器分块矩阵乘法的示意图如下:
矩阵乘法 kernel 的 FMA 指令寄存器分块示意
这里实际使用的是向量 - 标量乘加,拼凑出一个矩阵乘法外积的运算。x86 并没有直接从寄存器读取标量,和另一个向量做乘加的指令,所以这里需要额外的 broadcast 类指令帮忙把内存(实际在 L1 cache)中的标量数据广播给一个向量寄存器的所有通道。
低比特定点运算
单精度指令对于 AI 推理来讲,一般过于冗余,很多算法模型都可以将参数精度压缩到 8bit 定点。Intel 也在 AVX512 系列指令集中,单独加入了针对 int8 和 int16 点乘的 AVX512-VNNI 指令集。
DP4A 和 DP2A 类指令最早是 nvidia 在 Pascal 架构 GPU 中引入,每个 CUDA Core 有一个针对 int8 的 dp4a 单元。存储在 32 位寄存器中的 int8 向量,与另一个 int8 向量做点积运算(即 DP),中间结果和结果 32 位寄存器中的数据累加到一起,存回结果寄存器。DP2A 与之类似,只是把 8bit 数据换成 16 位的数据,如 int16,fp16 或者 bf16。后两类的结果寄存器也从 32 位整型,换成 fp32 浮点。
Intel 的 AVX512-VNNI 指令就是 DP4A/DP2A 类的指令,如下图所示:
Intel VNNI 指令集中使用的 dp4a/dp2a 类指令
AVX512-VNNI 支持 uint8 乘以 int8,以及 int16 乘以 int16 两种规格。在 512bit 寄存器上抽成 16 组 dp4a 或 dp2a 单元。这样相比 AVX-512f 的单精度乘加指令,乘加计算密度又有了 4 倍吞吐。因为 AVX512 指令集资源消耗过重,只在云端上放了完整的支持,桌面和移动端从 12 代酷睿开始,都取消了 AVX512 的支持。为了应对这种尴尬的局面,Intel 引入了 AVX-VNNI 指令,只支持 256bit 向量的 VNNI。同时,AVX512-VNNI 中的 256bit 指令,与 AVX-VNNI 的功能虽然完全相同,但使用不一样的指令编码,需要加上 {vex} 前缀。12 代以后的桌面和移动端 intel 处理器,开始支持这个指令集。同时 12 代开始的酷睿又引入了大小核的設定,gracemont 的小核心也开始加入 AVX-VNNI 的支持,只是 int8 吞吐量并没有单精乘加的 4 倍,只有 2 倍。然后 intel 发现 u8s8 和 s16s16 的方式似乎不够用,又找补了 AVX-VNNI-INT8 和 AVX-VNNI-INT16 两种新指令集,将 u8u8,s8s8,s8u8,u16s16,s16u16,u16u16 这六种组合方式也加入了进来,但还不知道会用在哪款 CPU 上。
从 SSE 到 AVX512-VNNI,单一指令的乘加计算吞吐量增大到 32 倍。
半精度指令
Intel 引入 VNNI 的时候,更多的是将 CPU 定位为推理算力。为了和 nvidia 更全面地竞争,intel 也想在 CPU 上做训练的支持,因此又引入了两种半精度浮点的支持:bfloat16 和 fp16。
同样也是在 AVX512 指令集系列里做的扩充,分别叫做 AVX512-bf16 和 AVX512-fp16。Intel 最早在第三代 Xeon Icelake SP 伺服器上引入的 AVX512-bf16,在第四代 Xeon Sapphire Rapids 引入了 AVX512-fp16。有趣的是,前者提供的是 dp2a 类型的指令,且除了和 fp32 的互转,没有提供更多的运算支持;后者提供的是标准的向量乘加指令,且有类似 fp32 的各类计算操作支持。两者的吞吐量,理论上都是 fp32 的两倍,补充了 VNNI 指令只支持定点的缺陷。
至此,Intel 在现有 SIMD 寄存器体系下对 AI 的支持已经完成。我们总结一下,这个体系下 intel 主要依靠增加单条指令的计算密度来提高吞吐,大致抽成两个方向:一个是增加向量的长度,从 128bit,到 512bit;另一个是压缩参数位数,从 32bit 浮点,到 8bit 定点。这两个方向都是线性增长,且都存在扩展上限,所以 intel 并没有满足于此,抛开现有 SIMD 体系,走上了在 CPU 核内增加特定 AI DSA 架构的路线。
专用的 DSA —— Intel AMX
AMX 是 Intel 针对矩阵乘法设计的全新 DSA,与 SIMD 指令的最大区别是,它抛开了现有 SIMD 的寄存器结构,引入了全新的 TILE 二维寄存器檔案。下图简单描绘了 AMX 的结构,每个处理器核心都拥有这样一个结构:
Intel AMX 基本结构
灰色框得標注的就是它独有的 TILE 寄存器体系,当前的版本(Sapphire Rapids ) ,TILE 寄存器的数量是 8,支持 int8 和 bf16 两种数据类型。TILE 的结构,其实就是一个二维 16×16 的方阵。方阵的元素是个 32bit 的数据,可以存 4 个 int8,2 个 bf16 或者 1 个 int32/fp32。AMX 的核心计算,就是将两个 TILE 中存储的矩阵相乘,累加到第三个矩阵中。下图展示了 AMX_INT8 的 TMUL 计算的矩阵乘法规模:
AMX_INT8 中 TMUL 操作示意图
每个 TILE 寄存器都是 16×16×4 字节的容量,在 int8 的 case 里,相当于计算了 16×16+=16×64×64×16 这样规模的矩阵乘,其中每四个 int8 通过 dp4a 操作累加到一个 int32。bf16 的操作类似,只是每两个 bf16 通过 dp2a 操作累加到 fp32,计算吞吐比 int8 小一倍。
这个过程的具体实现,是一个标准的脉动阵列。bf16 的计算指令是 TDPBF16PS,int8 的计算指令有四个:TDPB磁碟,TDPBSUD,TDPBUSD,TDPBUUD,就是 int8 和 uint8 的四种组合。每条计算指令启动一个矩阵乘法的脉动数据流。脉动阵列的时空流水较复杂,这里不详细描述,有非常多的文章介绍这个结构的原理。除了核心的 TMUL 计算指令,AMX 还提供了 load 和 store 数据的基础指令,对 TILE 清零的指令,以及配置计算规模和数据类型的 TILECFG 类指令。下面的表格里给出各个指令的延迟吞吐:
AMX 指令延迟和吞吐
其中 TDP 类核心计算指令,吞吐周期是 16,这意味着每隔 16 个周期可以发起一条新的数据无关的脉动流水计算指令;延迟周期是 52,表明这条脉动指令 52 周期后会计算完成,得到所有的 C 矩阵 16×16 个结果。根据我们以前讲到测试指令吞吐的方式,需要至少 ⌈5216⌉=4 条无依赖的指令排在一起,才能掩盖单个脉动流水的延迟。下面的代码可以测试 AMX 计算峰值:
tilezero %tmm0
tilezero %tmm1
tilezero %tmm2
tilezero %tmm3
tilezero %tmm4
tilezero %tmm5
.amx.int8.mm.s32s8s8:
tdpbssd %tmm4, %tmm5, %tmm0
tdpbssd %tmm4, %tmm5, %tmm1
tdpbssd %tmm4, %tmm5, %tmm2
tdpbssd %tmm4, %tmm5, %tmm3
sub $0x1, %rdi
jne .amx.int8.mm.s32s8s8
ret
具体用 AMX 优化矩阵乘法或者卷积还要考虑很多因素,比如 cache 上数据排布的转换。我们用上面代码的写法,在一台双路 64 核(每路 32 核)的 Xeon Sapphire Rapids 伺服器上测试了 AMX 的峰值,结果如下:
Xeon Sapphire Rapids 64 核伺服器 AMX 峰值测试
图左是单核的测试结果,图右是 64 核的测试结果。单核可以做到 7+Tops,这在 CPU 的历史上是独孤求败的存在;64 核可以做到接近 400Tops 的峰值,可以媲美很多云端大算力 AI 加速器的水平,且这还是最低端的一款 SPR,intel 还有单路 56 核的高端版本。
AMX 这种专用的 DSA,做到了 SIMD 里最高吞吐指令 VNNI 的 8 倍。而且从 intel 的文档和材料里看,这个结构的扩展性很强:从结构图里提到的 accelerator,当前版本还只有一个,后续版本可以扩展出更多;TILE 寄存器的容量和个数也都可以扩展;还可以增加更多的低精度数据类型。扩展维度非常多。至此,intel 想利用 CPU 去抗衡 GPU 的布局正式完成,Xeon CPU 正式长成一颗大算力的怪物,intel 甚至为它配上了 HBM 的版本。
关于生态
我们都知道 intel 在推出 64 位处理器时候犯下的错误:2001 年 Intel 推出安腾架构处理器(IA-64),对 32 位的 x86(IA-32)采取了完全不兼容的策略,使用了 VLIW 的指令集体系结构。在后来的一系列发展过程中,固然有 VLIW 架构在通用计算本身的性能问题,但是不兼容先前的 x86 和所有的 x86 軟體,导致用户軟體迁移的成本巨大,安腾的市场一直做不起来,最终早早退出历史舞台。同时 AMD 在 03 年抢先推出了 x86 的 64 位扩展,命名为 amd64,并兼容运行 32 位的 x86 程式,市场大范围跟进。这导致不久以后 intel 不得不开始兼容 amd64,甚至到现在为止,很多作業系統发行版对于 x64 的名字依然叫做 amd64。
x86 生态在 PC 和通用伺服器市场如此重要,导致 intel 后续在移动互联网,高性能计算和 AI 这些新战场的初期,都过于迷信 x86 生态,错过了快速迭代,占领用户心智的机会。移动互联网要求高度的可定制化,非常低的成本,arm 有天然的先发适配优势,且最初由苹果主导,x86 没有掀起任何水花;高性能计算和 AI 对单点性能,互联扩展性有极强的要求,nvidia GPU 顺应了时代,快速进步,并推出完整的解决方案,致使最初 intel 基于 Xeon Phi 的解决方案很快败下阵来。intel 在长达五六年的时间内没有拿出任何有竞争力的高性能计算加速方案,将这个市场拱手让给 nvidia。
Intel 现在 x86 处理器中塞入了过多重量级的计算负载,固然是对抗 nvidia 的无奈之举。然而本身也使自身的枷锁越来越沉重,甚至影响了自己的 server 市场:AMD 和 arm 都有各自的专用高性能和 AI 方案,不需要 CPU 过度负担,且通用单核性能早已追平 intel,在 server 端轻轻松松就可以堆到 128 核甚至更多,市场进展势如破竹。intel 却很难堆更多的核,甚至不得不启用自家小核(E 核)方案去做堆核方案,竞争力相当堪忧。Intel 需要尽快明确并坚持自己在 AI 领網域的专用加速方案,并与自家 x86 生态配合,为 x86 减负增效,回归本来的定位,否则连目前利润最高的伺服器市场都会被对手蚕食殆尽。
arm:RISC 还是 CISC?
arm 是 Advanced RISC Machine 的简称,一直以来标榜自己是 RISC 处理器。我们来看看 arm 对 RISC 的定义 What is RISC? – Arm®:
A Reduced Instruction Set Computer is a type of microprocessor architecture that utilizes a small, highly-optimized set of instructions rather than the highly-specialized set of instructions typically found in other architectures. RISC is an alternative to the Complex Instruction Set Computing ( CISC ) architecture and is often considered the most efficient CPU architecture technology available today.
然而当我们翻开 arm 的架构指令集文档 Arm Architecture Reference Manual,并和 intel 的同类型文档做个对比:
arm 和 intel 指令集文档页数对比
emmm... RISC 的 R 改成 Regular 好了 ...
arm AI 指令集的 SIMD 演进
回归正题,本节简要介绍一下 arm 在 SIMD 指令体系下对 AI 的支持。
arm 早年的 SIMD 指令使用 neon/asimd 这一套体系,这是一套仅有 128bit 长度的向量指令集。neon 的指令设计相比 x86 的向量指令大同小异,但更高效紧凑:neon 除了支持标准的向量 - 向量乘法,加法和乘加以外,还支持选择向量中的某条 lane(arm 术语,即向量中的某个位置的标量值),和另一条向量的所有 lane 做乘加,即标量 - 向量乘加。这样的指令设计,相比 x86 的 broadcast + 向量 - 向量乘加的指令组合,节省了指令数量和读取数据的次数。
arm 从 armv8.0 开始支持 fp32 和 fp64 的向量乘法,加法和乘加运算指令(asimd/fp);从 armv8.2 开始增加了 fp16 的支持(asimdhp),以及 int8 的 dp4a 指令支持(asimddp)。然后 arm 在 neon 现有的寄存器体系之上,又增加了针对 bf16 和 int8 的一种矩阵乘法指令模式 mmla,其中针对 bf16 的指令集就叫 bf16,针对 int8 的指令集叫做 i8mm,这两个指令集在 armv8.6 中引入。如下图所示:
mmla 类指令运算示意
这个系列的指令设计非常巧妙,输入向量 抽成两个 64 位向量 1 和 2 , 也抽成两个 64 位向量 1 和 2 ,根据数据类型,这四个向量可以是 8 个 int8,或者 4 个 bf16。两两一组做向量点积,得到四个 32 位结果(int8 点积结果 int32,bf16 点积结果 fp32)。累加到结果寄存器 的四个 32 位值里。由于输入向量的每个值都复用两次,所以这条指令的吞吐,比对应数据类型的 dp4a 或者浮点乘加有一倍的吞吐提升。mmla 和标量 - 向量计算类指令,都是 x86 目前所没有的设计。
arm 在伺服器端通过增加向量长度扩展指令吞吐,为此引入了 SVE/SVE2 这样一套新的 SIMD 指令,这两种指令集并不兼容 neon,但是功能是类似的,最大的变化是支持更长的向量(从 128bit 到 2048bit)。在移动端则是通过增大 SIMD 单元发射数量来扩展指令吞吐,而向量长度保持 128bit 不变。比如 Cortex-A57/A72 有一个 SIMD 单元;从 A76 开始增加到两个;Cortex-X1 系列开始增加到 4 个;最近发布的最新 Cortex-X925 更是一举扩展到 6 个。同时配合越来越低比特精度数据,以及乘加密度更高的指令设计,arm 在 AI 领網域的进步神速。
SME ——外积矩阵乘 DSA
苹果自家的 apple silicon 芯片在 2020 年正式发布,在 CPU 上引入了名为的 AMX 矩阵乘法 DSA,与 intel 的 AMX 同名,但是完全不同的设计。arm 也在 2021 年引入了新的指令集 SME,它包含了 SVE/SVE2,同时为矩阵乘法引入了类似苹果 AMX 的 DSA。
SME 里提供的矩阵乘法指令基于外积计算(outer product),如下图所示:
向量外积计算矩阵乘法
向量外积相当于做一次 =1 的矩阵乘法:TILE_C 是结果矩阵 C 的一个分块( × 维);VEC_A 是其在矩阵 A 中对应的水平 M 行条带分块中的一个列向量;VEC_B 是其在矩阵 B 中对应的垂直 N 列条带分块中的一个行向量;这两个向量分别读到向量寄存器中,进行一次外积计算,乘累加到 TILE_C,就完成了一次外积运算;然后沿着 A 和 B 当前的条带分块的 K 方向不断读取新的向量,形成计算流水线,最终计算完整个 TILE_C 的值,写回内存。
SME 为这个操作提供了全新的 Z Array 寄存器体系和 ZA Tiles 分块方式,并通过新指令提供对 A 和 B 矩阵条带分块的数据重排方案。实际上我们观察到,不管是 x86 还是 arm 的 SIMD 方案,也都是通过构造矩阵外积的寄存器分块方式进行计算的。只是它们提供的指令计算粒度,只能做标量和短向量的乘加,通过多条指令的组合,构造一个完整的外积矩阵乘法。而 SME 提供的外积指令,只需要一条指令即可做一个完整且大规模的外积乘法,这就是 DSA 对指令密度的提升。
向量外积有哪些特色呢:首先一次外积计算相当于 × 个乘加操作阵列,这些乘加操作之间理论上无数据依赖,可同时并行流水(实际上电路的布线可能会限制这个特点,M 和 N 不能大规模扩展);其次,向量外积是个非常简单的顺序 Streaming 读取重排后的矩阵 A 和 B,同时与计算操作进行重叠;最后,向量外积的读取和计算的比例最低,是 +/× ,对于读取带宽的需求有很大降低。
SME 的外积指令相比 mmla 指令,虽然都是矩阵乘法指令,但前者对读取数据的利用率更高,VEC_A 的每个数据复用了 N 次,VEC_B 的每个数据复用了 M 次;而 mmla 指令对读取数据只复用了两次。前者是建立在使用更庞大的寄存器檔案扩大了矩阵乘分块实现的,后者的好处是在现有 SIMD 寄存器体系下就可以轻松提升一倍的吞吐。
arm CPU 的 AI 能力是移动端生态建设的基石
最近 AI 手机,AI PC 刮起了一阵旋风,让各种大算力的移动 GPU 和 NPU 出尽了风头,然而 arm 的 CPU 仍然占有重要的地位。在手机端,目前有苹果,高通的 adreno,arm 自己的 mali,以及 imagination 等四种主要的移动 GPU 平台;PC 上有 nvidia,AMD 和 intel 等三种 GPU 平台。虽然有 OpenCL/Vulkan 等计算 API 可以写一套代码适配大部分 GPU,但不同的 GPU 架构要优化到位,还有很多特化的优化要去做。NPU 的生态就更破碎了,不同 NPU 的开发接口,编程能力完全不同,很难用一种统一的方式支持所有主流的移动 NPU。这对于手机和 PC 上的 App 开发者简直是噩梦。arm 架构的 CPU 虽然也有代际差异,但基本反映在支持的 AI 标准指令集的多寡。只要把本文提到的几种指令集都支持好,对不同芯片使用运行时识别指令集的方式支持本地最新的 AI 指令,就能把最通用的 AI 能力集成到自家 App 里。有了这基础通用的 AI 能力,可以再适配不同的 GPU 或者 NPU 方案,丰俭由人。
其它 CPU 架构:家家有本难念的经
其它种类的 CPU 在高性能的场景,如手机移动端,桌面 PC 或者伺服器端暂时都没有很大的使用量,更多还是用在 IoT,MCU 等场景,这些场景对 AI 也有很大的需求。
risc-v:繁荣还是混乱?
risc-v 是目前业界除 x86 和 arm 以外非常火爆的指令集架构,它是由开放社区制定的开源指令集标准,任何组织都可以免费使用其标准构筑自己的实现。不过 risc-v 是一种很新的架构,许多标准,例如 vector extension 这样的 SIMD 指令标准,是最近一两年才正式发布。在这前后有很多公司发布过自己的标准,造成了一些混乱。官方正式版的 vector extension 简称 rvv1.0,是一种很现代化的 SIMD 指令标准。它提供了针对 fp64/fp32/fp16 的基本乘加指令,对于 AI 的支持有个很好的基础。有些 risc-v 厂商在这个标准之外设计了自己的 AI 指令集,如进迭时空的 K1 芯片(为志坚兄做个广告 ~),通过测试可以看出 AI 能力有很大的提高:
SpacemiT K1 芯片带 AI 加速指令的四个核峰值测试
这在很多 IoT 场景甚至不用额外添加 NPU 了,而且与 CPU 本身的标量和 SIMD 指令配合,可以做到长尾算子的高效执行,某些情况下比 CPU + NPU 的组合还要好。
国产指令集—— loongarch
loongarch 是龙芯 2020 年左右以 mips 为蓝本发布的全新自研指令集标准,成为国产自主指令集的独苗。loongarch 目前支持 LSX 和 LASX 两种 SIMD 指令,分别是 128bit 和 256bit 向量长度。遗憾的是,由于种种原因,龙芯暂未公布 loongarch SIMD 指令的标准文档,我只 hack 出了基础的 fp32 和 fp64 的标准向量乘加指令,还不知道有没有针对 AI 的指令。龙芯的生态最近几年面临一些官司,同时由于一些历史原因,ABI 还抽成旧世界和新世界两种,可谓是一出道就陷入了泥潭。23 年 3A6000 的发布,在性能上已经让龙芯进入可用的程度,希望龙芯可以早日统一规格标准,快速适配国产生态环境。
写在最后
本文是个综述性的科普文章,把市面上现有流行的 CPU 架构对 AI 的支持简要过了一遍,技术上蜻蜓点水,也在关注一些历史逻辑和未来方向,观点或多有偏颇。希望这些内容对于初学者,或者关注相关领網域的朋友有所帮助。