今天小編分享的科技經驗: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 的支持簡要過了一遍,技術上蜻蜓點水,也在關注一些歷史邏輯和未來方向,觀點或多有偏頗。希望這些内容對于初學者,或者關注相關領網域的朋友有所幫助。