測(cè)試龍芯3A6000,結(jié)論:中國(guó)最有前途的CPU
計(jì)算能力已成為世界各國(guó)經(jīng)濟(jì)發(fā)展的重要資源,中國(guó)也不例外。該國(guó)在CPU領(lǐng)域投入了大量的資源,龍芯處于這一領(lǐng)域的最前沿。我們之前報(bào)道了該公司的3A5000 CPU,這是一款四核處理器,每時(shí)鐘周期的性能合理,但時(shí)鐘頻率太低,不具備競(jìng)爭(zhēng)力。
本文引用地址:http://cafeforensic.com/article/202403/456876.htm現(xiàn)在,我們來(lái)看看龍芯新推出的3A6000 CPU。3A6000也是四核2.5 GHz的規(guī)格,但使用了新設(shè)計(jì)的LA664核心。與3A5000的LA464核心相比,LA664的進(jìn)步當(dāng)刮目相看。雖然龍芯LA664延續(xù)了與LA464的指令集和微架構(gòu)設(shè)計(jì),但LA664具有更寬的流水線和更多的執(zhí)行單元。為了讓CPU效率更高,LA664增加了SMT(超線程)支持。如果對(duì)超線程的的實(shí)現(xiàn)得當(dāng),SMT可以用最小的芯片面積開銷提高多線程性能,但把SMT做好非常困難。
一、評(píng)估3A6000(Sizing Up 3A6000)
7-Zip是一個(gè)文件壓縮工具,它能達(dá)到很高的壓縮效率,但相對(duì)其它壓縮工具,它可能對(duì)CPU性能的要求也更高。它幾乎只使用標(biāo)量整數(shù)指令,所以SIMD擴(kuò)展不起作用。在這里,我們通過(guò)壓縮一個(gè)很大的ETL文件來(lái)測(cè)試3A6000的性能,評(píng)估指標(biāo)是壓縮速度,每秒壓縮的數(shù)據(jù)越多越好。
與前代相比,3A6000在不使用SMT(超線程)時(shí),運(yùn)行7-Zip的性能就已經(jīng)獲得了38%的巨大提升。如果加上SMT支持,這一提升還會(huì)增加。當(dāng)每個(gè)CPU核心只使用一個(gè)線程時(shí),四個(gè)LA664核心在7-Zip測(cè)試中大致相當(dāng)于四個(gè)頻率更高的Zen1核心。因此,LA664的每個(gè)時(shí)鐘周期的性能非常高(譯者注:在相同的頻率下,LA664的性能接近于Intel Raptor Lake核心和AMD Zen 4代核心 )。但因?yàn)樗辉?.5 GHz下運(yùn)行,由于頻率較低,使它的性能無(wú)法與AMD的新款CPU相比。
使用8個(gè)線程(4個(gè)物理核心)后,SMT(超線程)使3A6000運(yùn)行7-Zip時(shí)的性能再提高了20%,但AMD的Zen 1和Zen 2運(yùn)行7-Zip時(shí)能通過(guò)SMT獲得40%以上的收益。SMT的作用是為核心提供更明確的并行性,減少平均的運(yùn)行延遲并使流水線保持更加飽和的工作狀態(tài)。一方面,較高的SMT增益表明CPU核心的SMT實(shí)現(xiàn)經(jīng)過(guò)了很好的調(diào)整。另一方面,這意味著CPU核心在運(yùn)行單個(gè)線程時(shí)沒(méi)有很好地降低延遲。
(譯者注:7-Zip的性能測(cè)試只涵蓋了通用CPU性能評(píng)估的一小部分,有的CPU運(yùn)行7-Zip的效率很好,但運(yùn)行其它程序效率可能極差。比如在相同頻率下,10代酷睿一個(gè)核心的7-Zip測(cè)試成績(jī)不到Pentium4的3倍,但對(duì)于通用性能綜合測(cè)試,10代酷睿的單核同頻性能是Pentium4的5倍左右。)
與7-Zip不同,libx264視頻編碼大量使用SIMD指令。在x86 CPU上,編碼器將使用SSE、AVX、AVX2,甚至AVX-512(如果可用)。在龍芯上,libx264將利用LSX(128bit)和LASX(256bit) SIMD擴(kuò)展。在這里,我轉(zhuǎn)碼了一個(gè)《守望先鋒》的游戲剪輯4K視頻,所有CPU都只使用4個(gè)物理核心,評(píng)估指標(biāo)是每秒轉(zhuǎn)碼的幀數(shù),幀率越高越好。
在視頻轉(zhuǎn)碼測(cè)試中,當(dāng)啟用的核心數(shù)量相同時(shí),2.5GHz的3A6000性能可以與最高頻率超過(guò)4.0GHz的AMD 1800X相提并論。在使用SMT線程以及將任務(wù)限制為每個(gè)核心一個(gè)線程時(shí),它們的轉(zhuǎn)碼速度互有勝負(fù)。1800X使用Zen 1核心有較的高SMT增益,但可能受到其較弱的AVX2(256bit)實(shí)現(xiàn)的限制。3950X的Zen 2核心和3A6000都獲得了30%以上的SMT收益。憑借全面改進(jìn)的架構(gòu)和穩(wěn)固的AVX-512(512bit)實(shí)現(xiàn),AMD最新的7950X3D中使用的Zen 4核心脫穎而出。與之前一樣,3A6000僅憑借2.5 GHz的頻率,性能上的表現(xiàn)就相當(dāng)出色。
核心對(duì)核心,LA664把龍芯CPU從低性能的行列中帶了出來(lái),使3A6000能與AMD和Intel以往的高性能產(chǎn)品競(jìng)爭(zhēng)。Zen 1與Haswell大致相當(dāng),即使在今天,這兩種微結(jié)構(gòu)的CPU仍然可用。現(xiàn)在,讓我們來(lái)看看讓龍芯能與那些更高級(jí)的產(chǎn)品競(jìng)爭(zhēng)的核心微架構(gòu)。
(譯者注:libx264中的熱點(diǎn)代碼對(duì)龍芯LoongArch架構(gòu)的匯編優(yōu)化有所不足,特別是在向量指令的使用方面,通過(guò)編譯器直接產(chǎn)生的二進(jìn)制代碼很難比得上程序員細(xì)致調(diào)優(yōu)的手寫匯編代碼。)
二、核心架構(gòu)(Core Architecture)
LA664是一個(gè)6發(fā)射的支持亂序執(zhí)行的CPU核心,具有大量的執(zhí)行資源和深度的指令重排序能力。在這些方面,它具有與最新的英特爾和AMD核心競(jìng)爭(zhēng)的能力。
LA664是LA464演進(jìn)的結(jié)果。龍芯3A5000中的LA464核心是一個(gè)4發(fā)射的支持亂序執(zhí)行的核心,在各個(gè)方面的規(guī)格都比較適中。LA464是一個(gè)全面而實(shí)用的核心,幾乎沒(méi)有明顯的弱點(diǎn),為龍的進(jìn)步奠定了堅(jiān)實(shí)的基礎(chǔ)。毫無(wú)疑問(wèn),LA664繼承了LA464的微架構(gòu)設(shè)計(jì)。
當(dāng)然,框圖并不能說(shuō)明全部情況。分支預(yù)測(cè)、執(zhí)行延遲和內(nèi)存訪問(wèn)性能等因素都會(huì)產(chǎn)生巨大影響。
三、龍芯3A6000的前端(The Loongson 3A6000’s Frontend)
分支預(yù)測(cè)(Branch Prediction):
CPU分支預(yù)測(cè)器負(fù)責(zé)預(yù)判程序最可能執(zhí)行的分支,并把跳轉(zhuǎn)的方向告訴前端,這一點(diǎn)非常重要。因?yàn)槿绻种ьA(yù)測(cè)的方向錯(cuò)誤,CPU的后端在錯(cuò)誤的分支上運(yùn)行會(huì)浪費(fèi)大量的性能、電能和時(shí)間,并要再消耗一些時(shí)間才能回到正確的分支上。
3A6000的分支預(yù)測(cè)器具有令人印象深刻的模式識(shí)別能力,是迄今為止我們所見(jiàn)過(guò)的中國(guó)CPU中最好的。它與我們?cè)?A5000中看到的不同,3A5000與最新的Intel和AMD CPU相距甚遠(yuǎn)。然而,由于AMD一直在分支預(yù)測(cè)功能上大力投入,它們的Zen 3架構(gòu)仍然領(lǐng)先一步。
Zen 3通過(guò)一個(gè)覆蓋預(yù)測(cè)器(overriding predictor)來(lái)實(shí)現(xiàn)這一點(diǎn)。大多數(shù)分支具有簡(jiǎn)單的行為,并且可以由第一級(jí)快速處理,能力更強(qiáng)但速度較慢的第二級(jí)只需介入一些跨度較長(zhǎng)的分支即可。有了這個(gè)方案,Zen 3的分支預(yù)測(cè)器能夠在保持高速的同時(shí)跟蹤很長(zhǎng)的分支。
即使3A6000不能與AMD最新的核心相媲美,龍芯也取得了值得稱贊的進(jìn)步。3A5000的分支預(yù)測(cè)器看起來(lái)更適合從00年代中期到10年代初的高性能內(nèi)核,而不是最近這十年的東西。龍芯在這一領(lǐng)域的投入無(wú)疑是3A6000效率提升的一個(gè)重要因素。
分支預(yù)測(cè)器速度(Branch Predictor Speed):
分支預(yù)測(cè)器必須既快速又準(zhǔn)確,以避免核心空載浪費(fèi)時(shí)間。分支目標(biāo)緩沖區(qū)(Branch Target Buffers,BTB)用來(lái)緩存分支目標(biāo),使預(yù)測(cè)器跟隨指令流,而無(wú)需等待實(shí)際的分支指令出現(xiàn)。LA664有一個(gè)64條目的L1 BTB,能夠快速處理連續(xù)預(yù)測(cè),在AMD的術(shù)語(yǔ)中稱為“零氣泡(zero bubble)”。BTB未命中的時(shí)候,很可能是通過(guò)簡(jiǎn)單地等待指令字節(jié)從64KB的指令緩存到達(dá),然后通過(guò)分支地址計(jì)算器來(lái)計(jì)算目的地來(lái)處理的,這實(shí)際上看起來(lái)像是綁定到指令緩存的1K-4K條目的L2 BTB。
相比之下,AMD和Intel最新的微架構(gòu)使用了與指令緩存解耦的大型L2甚至L3 BTB。從另一個(gè)BTB級(jí)別獲取地址可能比等待指令字節(jié)到達(dá)更快,AMD的Zen 4利用這一點(diǎn),只要BTB包含了這個(gè)分支,就可以實(shí)現(xiàn)延遲非常低的分支處理。
此外,將BTB與指令緩存解耦有助于在代碼塊超出L1i容量時(shí)保持高IPC,因?yàn)轭A(yù)測(cè)器與L1i未命中時(shí)產(chǎn)生的延遲隔離。但龍芯不是唯一一種放棄龐大的、解耦的BTB設(shè)計(jì)的CPU,Tachyum-Prodigy同樣認(rèn)為這種方法過(guò)于昂貴,因?yàn)樗麄兒茈y用標(biāo)準(zhǔn)的單元庫(kù)達(dá)到頻率目標(biāo)。與Tachyum的Prodigy一樣,3A6000通過(guò)使用64KB的大指令緩存來(lái)補(bǔ)償這一點(diǎn)。如果預(yù)測(cè)器必須處理較少的L1i未命中延遲,那么這一些弱點(diǎn)就無(wú)關(guān)緊要了。
3A6000似乎還具有更積極的線性指令預(yù)取功能。上面的測(cè)試只是讓分支跳到下一個(gè)16字節(jié)對(duì)齊的塊,所以線性指令預(yù)取器可以很好地處理。相比之下,AMD的預(yù)取似乎完全由分支預(yù)測(cè)器驅(qū)動(dòng)。一旦我們超過(guò)了BTB容量,我們基本上都會(huì)看到L2延遲。
間接分支預(yù)測(cè)(Indirect Branch Prediction):
間接分支比直接分支更難預(yù)測(cè)。間接分支要跳轉(zhuǎn)到的目標(biāo)不是直接編碼到程序中,而是跳轉(zhuǎn)到寄存器中的地址,3A6000在間接分支預(yù)測(cè)方面做得很好。
3A6000總共可以跟蹤1024個(gè)間接目標(biāo),是3A5000的兩倍。3A5000只能跟蹤大約24個(gè)獨(dú)立的間接分支,而3A6000可以跟蹤128個(gè)以上獨(dú)立的間接分支。相比之下,Zen 2也可以跟蹤1024個(gè)間接目標(biāo),因此3A6000與最新的x86 CPU非常一致。
“返回”預(yù)測(cè)(Return Prediction):
“返回(Return)”操作是一種特殊的間接分支,通常與子程序調(diào)用(Call)成對(duì)出現(xiàn)。對(duì)于許多計(jì)算機(jī)處理器來(lái)說(shuō),使用堆棧來(lái)保存要返回的地址是很常見(jiàn)的。當(dāng)分支預(yù)測(cè)器發(fā)現(xiàn)調(diào)用(Call)指令時(shí),它會(huì)將當(dāng)前地址推入該堆棧。當(dāng)它遇到返回(Return)指令時(shí),它會(huì)從堆棧中彈出一個(gè)地址。奇怪的是,3A6000最終將返回堆棧從3A5000中的32個(gè)條目減少到只有16個(gè)條目。如果兩個(gè)核心的SMT線程都處于活動(dòng)狀態(tài),則有效容量可能會(huì)進(jìn)一步下降到8個(gè)條目。
將返回堆棧容量降至16個(gè)條目在一定程度上是合理的,因?yàn)榧词故禽^小的返回堆棧也可以捕獲大多數(shù)調(diào)用/返回情況。龍芯CPU可能是用間接分支預(yù)測(cè)器來(lái)處理超出條目數(shù)量的情況,因?yàn)槌^(guò)返回堆棧能容納的數(shù)量時(shí),3A6000只會(huì)出現(xiàn)適度的性能下降。英特爾也采用了同樣的策略,在這種情況下,返回堆??梢员灰暈閷?duì)功率和性能優(yōu)化,而不是性能的關(guān)鍵。
分支預(yù)測(cè)精度(Branch Prediction Accuracy):
7-Zip和其它壓縮工作負(fù)載通常給CPU分支預(yù)測(cè)帶來(lái)巨大挑戰(zhàn)。3A6000的分支預(yù)測(cè)器處理能力令人欽佩,對(duì)每條指令的預(yù)測(cè)失誤方面與Zen 1不相上下,在準(zhǔn)確性方面,3A6000與Zen 2平分秋色,在這種情況下,準(zhǔn)確性是一個(gè)更好的指標(biāo),因?yàn)?A6000完成工作執(zhí)行指令的更少。
因?yàn)長(zhǎng)oongson的指令流中有更大比例的指令由分支組成,所以每條指令的預(yù)測(cè)失誤率更高。AMD最新的Zen 4架構(gòu)仍然領(lǐng)先一步,但龍芯在其分支預(yù)測(cè)器方面取得了值得稱贊的進(jìn)展,3A6000令3A5000望塵莫及。
libx264具有更少的且更容易預(yù)測(cè)的分支,但我們?nèi)匀豢梢钥吹綔y(cè)試的CPU之間的差異。在這個(gè)測(cè)試中,ISA(指令集)差異對(duì)龍芯有效。3A6000每條指令很少出現(xiàn)預(yù)測(cè)失誤,但這是因?yàn)樗鼒?zhí)行了更多的指令來(lái)完成工作。當(dāng)有更多的非分支指令需要處理時(shí),預(yù)測(cè)失誤的比例就會(huì)降低。
(譯者注:libx264的熱點(diǎn)代碼對(duì)龍芯LoongArch指令集的匯編優(yōu)化有所不足,通過(guò)編譯器直接產(chǎn)生的二進(jìn)制代碼通常會(huì)比優(yōu)秀程序員手寫的匯編代碼冗長(zhǎng)一些。)
3A6000分支預(yù)測(cè)器的性能與AMD的Zen 2旗鼓相當(dāng)。龍芯再次表明,在設(shè)計(jì)準(zhǔn)確的預(yù)測(cè)器方面,他們可以和巨人一起玩。
指令獲?。↖nstruction Fetch):
一旦分支預(yù)測(cè)器決定了代碼的前進(jìn)方向,目標(biāo)代碼就會(huì)被加載到指令緩存中,并保留數(shù)據(jù)便于CPU核訪問(wèn)代碼。和3A5000差不多,3A6000有一個(gè)64KB的4路L1i(一級(jí)指令緩存),與只有32KB L1i的英特爾和AMD CPU相比,這是一個(gè)不錯(cuò)的L1i。64KB的L1i以及6個(gè)解碼器,使3A6000的前端比上一代產(chǎn)品加寬了50%。
AMD和英特爾的高性能CPU使用微操作緩存,這可以避免指令解碼成本,同時(shí)提供更高的吞吐量。自Zen以來(lái),AMD的微操作緩存理論上每個(gè)周期可以提供8個(gè)微操作,但核心的吞吐量受到下游重命名階段的限制。
龍芯3A6000在代碼塊大小超出L1i容量仍時(shí)保持了良好的吞吐量。3A5000在從L2運(yùn)行代碼時(shí)會(huì)莫名其妙地遭遇指令帶寬降低的問(wèn)題,龍芯在3A6000中解決了這一問(wèn)題。當(dāng)代碼在L2中時(shí),3A6000可以輕松地每周期執(zhí)行3條指令。
不幸的是,當(dāng)代碼在L3中時(shí)的情況并不樂(lè)觀,看起來(lái)3A6000似乎沒(méi)有改進(jìn)從L3獲取指令的能力。這是一個(gè)遺憾,因?yàn)镚olden Cove和Zen 3每個(gè)周期都可以獲得3個(gè)4字節(jié)的指令,而龍芯CPU每個(gè)周期獲得4字節(jié)指令的數(shù)量低于2個(gè)。
四、重命名和分配(Rename and Allocate)
一旦指令被解碼為微操作,核心就必須分配后端跟蹤資源(譯者注:一般為指令重排序緩沖區(qū)和內(nèi)存重排序緩沖區(qū))。這些資源將會(huì)跟蹤指令狀態(tài),并讓核心在輸入的數(shù)據(jù)準(zhǔn)備好后立即執(zhí)行指令,同時(shí)仍然確保正確的程序行為和異常處理。這個(gè)階段還通過(guò)寄存器重命名消除了依賴關(guān)系,并且是實(shí)現(xiàn)動(dòng)態(tài)調(diào)度以及使用各種技巧為指令執(zhí)行增加額外并行性的重要環(huán)節(jié)。
LA664的重命名器對(duì)寄存器清零有一種特殊的方式,x86 CPU總是通過(guò)XOR操作把寄存器清零,LA664不使用此類操作,這意味著清零操作不會(huì)消耗運(yùn)算單元的資源。
龍芯的重命名器還對(duì)寄存器到寄存器的移動(dòng)進(jìn)行了一些優(yōu)化。每個(gè)周期能執(zhí)行兩個(gè)move r,r指令,因此LA664有時(shí)可以在寄存器別名表中進(jìn)行指針操作,以打破這種依賴關(guān)系。然而,它不能以全速率進(jìn)行,并且寄存器到寄存器的移動(dòng)仍然需要ALU(算術(shù)邏輯運(yùn)算器)參與。
英特爾和AMD都開發(fā)了更先進(jìn)的重命名器,能夠完全消除寄存器到寄存器的移動(dòng),而不考慮依賴性。Intel的Golden Cove還可以在重命名階段通過(guò)較小的即時(shí)性添加來(lái)消除添加,進(jìn)一步減少執(zhí)行單元的負(fù)載。
五、亂序執(zhí)行(Out of Order Execution)
為了實(shí)現(xiàn)亂序執(zhí)行,在重命名和分配階段必須在必要的隊(duì)列和緩沖區(qū)中找到條目來(lái)跟蹤指令狀態(tài)。更大的緩存區(qū)可以讓核心在指令流中回溯更遠(yuǎn),從而更好地發(fā)現(xiàn)可以并行的指令。龍芯3A6000有一個(gè)規(guī)模較大的亂序引擎,比3A5000有了很大的進(jìn)步。
與3A5000相比,寄存器堆和內(nèi)存重排序隊(duì)列等主要結(jié)構(gòu)的大小至少增加了25%。LA464的分支順序緩沖區(qū)過(guò)小,LA664對(duì)此進(jìn)行了改進(jìn)。LA664最終具有與AMD的Zen 3相當(dāng)?shù)闹匦屡判蚰芰?。與英特爾的Golden Cove相比,Zen 3和LA664仍然很小,后者擁有巨大的512個(gè)條件的ROB和其它更大的結(jié)構(gòu)。
六、超線程實(shí)施(SMT Implementation)
更大的亂序緩沖區(qū)對(duì)于提高單線程性能至關(guān)重要,但增大緩沖區(qū)的回報(bào)會(huì)很快減少。SMT通過(guò)向操作系統(tǒng)提供多個(gè)邏輯核心并在線程之間劃分資源來(lái)抵消這些遞減的回報(bào)。因此,啟用SMT的CPU可以保持最大的單線程性能,同時(shí)在多個(gè)硬件線程空閑時(shí)能像幾個(gè)較小的核心一樣工作。AMD、Intel和龍芯都是每個(gè)核心暴露兩個(gè)SMT線程。
雖然SMT的好處顯而易見(jiàn),但實(shí)施起來(lái)卻很困難。當(dāng)操作系統(tǒng)在多個(gè)硬件線程上調(diào)度工作時(shí),核心必須實(shí)時(shí)重新配置自己。工程師必須決定如何在兩個(gè)線程的模式下管理各種核心資源。也就是說(shuō),SMT的結(jié)構(gòu)可以是:
雙倍資源:每個(gè)線程都擁有資源的一個(gè)副本。在一線程模式下,第二個(gè)副本只是未使用。這會(huì)浪費(fèi)芯片的面積,但可能更容易調(diào)整和驗(yàn)證。不必?fù)?dān)心資源會(huì)被一個(gè)線程耗盡,當(dāng)?shù)诙€(gè)線程也處于活動(dòng)狀態(tài)時(shí)就無(wú)法獲得可用的資源。
靜態(tài)分配:每個(gè)線程獲得一半的資源。當(dāng)一個(gè)線程處于停止?fàn)顟B(tài)時(shí),另一個(gè)線程可以使用所有條目,因此這種方法能更有效利用芯片面積。但這很難驗(yàn)證,因?yàn)楫?dāng)兩個(gè)線程都工作時(shí),資源將不得不被耗盡并重新配置。但調(diào)整仍然不太難,因?yàn)閷①Y源分成兩半可以確保線程之間的某種程度的公平性。
動(dòng)態(tài)調(diào)整:在雙線程模式下,一個(gè)線程消耗的資源條目可以超過(guò)一半。這有更大的靈活性和更潛在的性能,但調(diào)優(yōu)更難。更高的資源分配可以提高一個(gè)線程的性能,但對(duì)另一個(gè)線程會(huì)產(chǎn)生不成比例的影響(使其缺乏關(guān)鍵資源)。
競(jìng)爭(zhēng)性共享:所有線程都是自由使用所有資源。即使一個(gè)線程處于活動(dòng)狀態(tài),另一個(gè)線程也可以使用所有條目,靈活性和潛在性能最大化。例如,如果一個(gè)線程正在運(yùn)行浮點(diǎn)代碼,而另一個(gè)線程在運(yùn)行純整數(shù)代碼,那么競(jìng)爭(zhēng)性地共享調(diào)度器將使兩個(gè)線程都能滿足資源需求。但調(diào)整和驗(yàn)證變得更加困難,缺少資源是一種更常見(jiàn)的可能性,工程師們必須小心避免這種情況。
龍芯選擇了一種保守的SMT實(shí)現(xiàn)方式,其中大多數(shù)資源都是靜態(tài)分配的。包括ROB、寄存器文件和加載/存儲(chǔ)隊(duì)列。
3A6000上的部分資源是動(dòng)態(tài)調(diào)整,整數(shù)運(yùn)算調(diào)度器最高似乎能使用30個(gè)條目左右,因此即使SMT同級(jí)線程處于活動(dòng)狀態(tài),運(yùn)行在3A6000上的線程也可以與在3A5000上運(yùn)行時(shí)使用幾乎一樣多的調(diào)度器條目。
AMD的Zen 2靜態(tài)地劃分重排序緩沖區(qū),并對(duì)浮點(diǎn)運(yùn)算調(diào)度器和非調(diào)度隊(duì)列使用某種動(dòng)態(tài)分配方案。但除此之外,AMD選擇了一種非常激進(jìn)的SMT實(shí)現(xiàn)方式。寄存器文件、加載隊(duì)列和整數(shù)調(diào)度器是競(jìng)爭(zhēng)性共享的。這可以部分解釋Zen 2令人印象深刻的SMT提升。
對(duì)于龍芯來(lái)說(shuō),采取一種不那么激進(jìn)、更容易驗(yàn)證的方法可能是合理的。3A6000是他們的第一款支持SMT的CPU,過(guò)于雄心勃勃反而是容易失敗的路線。
七、整數(shù)運(yùn)行(Integer Execution)
3A6000的整數(shù)執(zhí)行部件與前代相比變化最小,但增加的50%的調(diào)度條目應(yīng)該會(huì)提高ALU(算術(shù)邏輯單元)利用率。與3A5000一樣,3A6000有四個(gè)ALU部件,能夠執(zhí)行最常見(jiàn)的操作。兩個(gè)端口可以處理分支,兩個(gè)端口可用于整數(shù)乘法,這樣的設(shè)計(jì)與Zen 2大致相當(dāng)。但與Zen 2相比,龍芯有兩個(gè)整數(shù)乘法部件。Zen 2具有更大的總調(diào)度能力,但將Zen 2的分布式調(diào)度器與龍芯的統(tǒng)一調(diào)度器進(jìn)行比較并不簡(jiǎn)單。Zen 2可能會(huì)遇到16個(gè)入口隊(duì)列中的其中一個(gè)在其他隊(duì)列之前填滿的情況,這將導(dǎo)致重命名器處的資源停滯。
龍芯將整數(shù)除法吞吐量從3A5000的0.11指令/周期提高到了0.25指令/周期,把延遲從9周期降低到了4周期。這種改進(jìn)是一個(gè)奇怪的選擇,因?yàn)榇蠖鄶?shù)代碼避免使用除法指令,因?yàn)樗鼈儚囊郧暗浆F(xiàn)在都非常慢。也許是因?yàn)辇埿颈仨殢念^開始構(gòu)建他們的軟件生態(tài)系統(tǒng),所以增加晶體管的數(shù)量提高運(yùn)算單元的速度是值得的。
八、矢量和浮點(diǎn)運(yùn)行(Vector and Floating Point Execution)
龍芯的3A5000具有LASX擴(kuò)展的256位矢量功能,但采用了僅兩個(gè)256位單元的保守實(shí)現(xiàn)。3A6000對(duì)FPU進(jìn)行很大的修改,它現(xiàn)在有四個(gè)執(zhí)行單元。所有四個(gè)單元都可以處理封裝為256位的浮點(diǎn)加法運(yùn)算,使3A6000具有非常強(qiáng)的浮點(diǎn)性能。競(jìng)爭(zhēng)對(duì)手(譯者注:兆芯和海光)的x86 CPU每個(gè)周期只能進(jìn)行兩次封裝為256位的浮點(diǎn)運(yùn)算。龍芯對(duì)封裝為256位的浮點(diǎn)乘法和基本整數(shù)運(yùn)算的性能與Zen 2相似。
奇怪的是,標(biāo)量浮點(diǎn)運(yùn)算并沒(méi)有得到同樣的增強(qiáng),只有兩個(gè)部件可以處理標(biāo)量浮點(diǎn)運(yùn)算。更奇怪的是,標(biāo)量浮點(diǎn)乘法似乎使用了與矢量乘法不同的單元。
盡管龍芯增加了額外的浮點(diǎn)單元,使整體的浮點(diǎn)性能有所提升,但峰值融合乘加(FMA)吞吐量沒(méi)有改變。LA464和LA664每個(gè)周期都可以執(zhí)行一次FMA操作,使其FMA吞吐量達(dá)到AMD的Zen 2或Intel Skylake的一半。
除了提高吞吐量,龍芯還降低了執(zhí)行延遲,浮點(diǎn)加法的延遲為3個(gè)周期,與Zen 3一樣。然而,AMD的Zen 3和英特爾的Golden Cove總體上仍然具有更低的浮點(diǎn)執(zhí)行延遲。尤其英特爾可以在2個(gè)周期延遲的情況下完成浮點(diǎn)加法,并且在更高的時(shí)鐘頻率下也可以做到。
與整數(shù)功能一樣,浮點(diǎn)調(diào)度程序條目也增加了50%,達(dá)到48個(gè)條目。這本身可能比額外的執(zhí)行單元提供了更多的浮點(diǎn)性能提升,兩者共同使3A6000在矢量和浮點(diǎn)工作負(fù)載方面成為一款強(qiáng)大的CPU。
AMD的Zen 2也有四個(gè)FPU(浮點(diǎn)計(jì)算單元),也可以將所有四個(gè)單元用于基本的矢量整數(shù)運(yùn)算。然而,它使用了一個(gè)巧妙的非調(diào)度隊(duì)列,即使36個(gè)條目的調(diào)度器已滿,也可以避免重命名器停滯。這使得后端可以動(dòng)態(tài)地保存更多的浮點(diǎn)或矢量操作,即使它不能通過(guò)搜索這些操作來(lái)找到額外的指令級(jí)并行性。
九、地址生成(Address Generation)
與LA464相比,龍芯在LA664上極大提高了地址生成能力。LA464有兩個(gè)通用裝載(讀內(nèi)存)/儲(chǔ)存(寫內(nèi)存)部件,LA664將其分成兩個(gè)裝載(讀內(nèi)存)部件和兩個(gè)儲(chǔ)存(寫內(nèi)存)部件。
這意味著LA664每周期可以處理比Zen 3更多的標(biāo)量?jī)?nèi)存操作,并且可以處理與Golden Cove相同數(shù)量的內(nèi)存操作。不過(guò)Zen 3和Golden Cove更靈活,因?yàn)榕cLA664的每個(gè)循環(huán)2個(gè)裝載操作相比,它們?cè)谝粋€(gè)循環(huán)中最多可以發(fā)出3個(gè)裝載操作,但這是對(duì)LA464的每個(gè)循環(huán)單個(gè)操作的重大升級(jí)。至于向內(nèi)存寫入數(shù)據(jù),LA664、Zen 3和Golden Cove(12代酷睿)在每個(gè)周期都是2個(gè)標(biāo)量?jī)?chǔ)存操作,而LA464在每個(gè)周期只能處理一個(gè)儲(chǔ)存操作。LA664每個(gè)周期可以處理兩個(gè)256位矢量訪問(wèn),這些也可以是加載和存儲(chǔ)的任意組合。
十、內(nèi)存排序(Memory Ordering)
一旦生成了地址,加載/存儲(chǔ)單元就必須確保內(nèi)存訪問(wèn)看起來(lái)是按程序順序執(zhí)行的(譯者注:會(huì)根據(jù)實(shí)際的指令執(zhí)行順序調(diào)整內(nèi)存訪問(wèn)順序)。加載時(shí)也可能必須從剛剛進(jìn)行的存儲(chǔ)中獲取結(jié)果(譯者注:執(zhí)行內(nèi)存寫操作后,數(shù)據(jù)要數(shù)個(gè)周期后才能真正地保存到內(nèi)存中,此時(shí)不能從內(nèi)存中加載剛剛存儲(chǔ)的數(shù)據(jù)),與先前的3A5000一樣,3A6000可以處理從大約7個(gè)周期內(nèi)的先前存儲(chǔ)中加載的情況。部分重疊的情況會(huì)導(dǎo)致14個(gè)周期的損失,可能加載操作會(huì)被阻塞,直到存儲(chǔ)操作完成并寫回L1D(一級(jí)數(shù)據(jù)緩存)。
Zen 2具有相同的7周期延遲和14周期部分重疊產(chǎn)生的損失,但Zen 2可以處理64字線緩存上的轉(zhuǎn)發(fā),只需額外的周期損失,而龍芯則很難處理這種情況。由于Zen 2可以運(yùn)行的頻率比LA664高得多,因此7個(gè)周期的轉(zhuǎn)發(fā)延遲對(duì)于龍芯來(lái)說(shuō)損失的時(shí)間更長(zhǎng)。Goldmont Plus的目標(biāo)頻率在2 GHz以上,具有5個(gè)周期的存儲(chǔ)轉(zhuǎn)發(fā)延遲和10個(gè)周期的故障情況。
LA664的存儲(chǔ)轉(zhuǎn)發(fā)行為看起來(lái)很像它的上一代,但LA664消除了因地址未對(duì)齊(譯者注:通常當(dāng)內(nèi)存地址不是4或8的整數(shù)倍時(shí)就是未對(duì)齊)而造成的10個(gè)周期的損失,并將其降至僅3個(gè)周期。這方面LA664比Zen 2稍微好一點(diǎn),Zen 2需要2到5個(gè)周期來(lái)處理地址未對(duì)齊的存儲(chǔ)。
跨越64字節(jié)邊界的存儲(chǔ)轉(zhuǎn)發(fā)處理仍然很差,但損失已經(jīng)從31個(gè)周期下降到了可以容忍的21個(gè)周期。
下面分別是3A6000和3A5000存儲(chǔ)到加載轉(zhuǎn)發(fā)延遲測(cè)試,使用Henry Wong的方法測(cè)量,代碼由Clam基于LoongArch指令集編寫:
十一、緩存和內(nèi)存訪問(wèn)(Cache and Memory Access)
良好的緩存和內(nèi)存層次結(jié)構(gòu)對(duì)于保持現(xiàn)代高性能CPU的數(shù)據(jù)供應(yīng)至關(guān)重要。3A6000保留了與3A5000類似的緩存層次結(jié)構(gòu),但總體上略有改進(jìn)。
由于龍芯CPU無(wú)法動(dòng)態(tài)提高時(shí)鐘速度,因此他們通過(guò)縮短流水線訪問(wèn)緩存的路徑減少延遲。
延遲(Latency):
3A6000的L1D(一級(jí)數(shù)據(jù)緩存)延遲從3A5000的四個(gè)周期下降到了三個(gè)周期。我認(rèn)為低時(shí)鐘CPU的目標(biāo)就是3個(gè)周期的L1D延遲,很高興在3A6000上看到這一點(diǎn)。
許多現(xiàn)代CPU將L2(二級(jí)緩存)用作中間緩存,以便在L1(一級(jí)緩存)未命中時(shí)與延遲相對(duì)較高的L3(三級(jí)緩存)隔離開來(lái)。3A6000與以前的Intel CPU一樣,繼續(xù)使用256 KB的二級(jí)緩存,較新的AMD和Intel CPU傾向于使用更大的L2。Zen 4使用了1MB的L2,而英特爾的Raptor Lake則選擇了2MB的L2。盡管龍芯沒(méi)有實(shí)現(xiàn)更大的L2,但他們確實(shí)設(shè)法將延遲從14個(gè)周期降低到了12個(gè)周期。假設(shè)L1以相同的速度處理命中和未命中,L1到L2的路徑可能只減少了一個(gè)流水線級(jí)。
Zen 2、3A6000和3A5000都具有一個(gè)由四個(gè)核心共享的16 MB L3緩存。3A6000將L3延遲減少了幾個(gè)周期,盡管這可能是因?yàn)闄z查L(zhǎng)2的速度快了兩個(gè)周期。
最后,訪問(wèn)DRAM的延遲從144ns縮短到了104ns。3A5000有一個(gè)(延遲)可怕的DDR4控制器,它之所以被使用,是因?yàn)樗倪\(yùn)行頻率較低,意味著雖然延遲時(shí)間較高,但時(shí)鐘周期計(jì)數(shù)卻和主流產(chǎn)品相近,也就是說(shuō)對(duì)IPC的影響很小。
3A6000的內(nèi)存控制器得到極大的改進(jìn),雖然104 ns的延遲仍然不太好,但它的周期計(jì)數(shù)方面的延遲遠(yuǎn)低于頻率更高的3950X。因此,3A6000至少通過(guò)減少DRAM存取延遲的周期弱化了低頻率的一些缺點(diǎn)。盡管如此,對(duì)于單片芯片上的DDR4-2666設(shè)置來(lái)說(shuō),104 ns并不是很好。
雖然3A6000的周期計(jì)數(shù)延遲具有競(jìng)爭(zhēng)力,但我們必須考慮實(shí)際延遲時(shí)間。因?yàn)辇埿镜腃PU頻率無(wú)法接近現(xiàn)代AMD和Intel CPU,它在包括L1在內(nèi)的每個(gè)緩存級(jí)別都較慢。這就解釋了為什么盡管LA664有比Zen 2更強(qiáng)的重新排序能力和更高的IPC,但基于LA664的3A5000在很多方面反而不如基于Zen 2的產(chǎn)品。
帶寬(Bandwidth):
內(nèi)存帶寬會(huì)影響性能,尤其是對(duì)于矢量化的多線程應(yīng)用程序。3A6000在很大程度上繼承了上一代的內(nèi)存層次結(jié)構(gòu),但龍芯再次在各個(gè)方面進(jìn)行了改進(jìn)。
3A5000的每周期L1D帶寬就已經(jīng)與英特爾的Skylake或AMD的Zen 2類似了,3A6000則通過(guò)改進(jìn),實(shí)現(xiàn)了寫入帶寬翻倍?;旧?,3A6000的任何寫入和讀取組合都可以在每個(gè)時(shí)鐘周期以256bit的位寬訪問(wèn)兩次L1D。
因此,盡管3A6000的頻率很低,但它具有令人印象深刻的L1D寫入帶寬。LA664打破了Golden Cove的唯一,和它一起成為了存儲(chǔ)帶寬達(dá)到每個(gè)周期512bit(譯者注:原文此處誤寫為byte)的面向消費(fèi)市場(chǎng)的CPU核心。
下圖是三款CPU的單線程讀寫緩存和內(nèi)存時(shí)的帶寬,其中AMD是服務(wù)器CPU的數(shù)據(jù),因?yàn)槲沂稚现挥羞@個(gè)數(shù)據(jù)。訪問(wèn)小尺寸數(shù)據(jù)時(shí)是CPU內(nèi)部的L1、L2、L3緩存在起作用,隨著讀寫數(shù)據(jù)的尺寸增加,超過(guò)緩存的容量后,會(huì)很快降低到訪問(wèn)物理內(nèi)存時(shí)的讀寫帶寬。
?。ㄗg者注:從本文后面的內(nèi)容可知,作者測(cè)試龍芯CPU時(shí)是使用的DDR4-2666內(nèi)存,但3A5000及3A600都支持DDR4-3200內(nèi)存,因?qū)?nèi)存帶寬的測(cè)試結(jié)果沒(méi)有完全體現(xiàn)出龍芯CPU訪問(wèn)內(nèi)存的速度。)
下圖是三款CPU多線程讀寫內(nèi)存時(shí)的帶寬:
LA664的256KB L2基本上與上一代相同,每個(gè)讀取帶寬周期有21-22字節(jié),寫入帶寬相同。因此,3A6000的每周期L2帶寬仍然低于AMD或Intel 最新的任何CPU。與Intel CPU相比,這一差距變得特別大,后者到L2的路徑每周期能訪問(wèn)64字節(jié)。
下圖是三款CPU每個(gè)時(shí)鐘周期的內(nèi)存訪問(wèn)帶寬:
在訪問(wèn)L3的階段,LA664的帶寬比前代增加了33%。L3的18.7字節(jié)/周期使龍芯的表現(xiàn)好于以前的英特爾CPU,但AMD異常強(qiáng)大的L3實(shí)現(xiàn)仍然領(lǐng)先。
為多個(gè)核心設(shè)計(jì)共享的緩存帶來(lái)了額外的挑戰(zhàn),因?yàn)楸仨殧U(kuò)展緩存帶寬以滿足多個(gè)核心的訪問(wèn)。當(dāng)所有硬件線程都在載入數(shù)據(jù)時(shí),3A6000可以在每個(gè)時(shí)鐘周期為每個(gè)核心提供16.55個(gè)字節(jié)。這比在只有一個(gè)核心運(yùn)行而沒(méi)有其他核心競(jìng)爭(zhēng)的情況下所能得到的只少一點(diǎn),總體上表現(xiàn)非常好。較舊的3A5000在所有四個(gè)內(nèi)核都已加載的情況下,每個(gè)內(nèi)核每個(gè)周期只能提供略高于10個(gè)字節(jié)的數(shù)據(jù),而在單個(gè)內(nèi)核處于活動(dòng)狀態(tài)的情況下每個(gè)周期可以提供13.7個(gè)字節(jié)。這表明3A5000的L3在多核同時(shí)訪問(wèn)時(shí)存在爭(zhēng)搶,3A6000在很大程度上解決了這一問(wèn)題。AMD的Zen 4再次提供卓越的L3帶寬,即使多個(gè)內(nèi)核正在訪問(wèn)緩存,每個(gè)內(nèi)核的每個(gè)周期也超過(guò)24字節(jié)。
龍芯的3A5000有一個(gè)糟糕得可怕的DDR4控制器。謝天謝地,3A6000有一個(gè)更好的。它在技術(shù)上支持DDR4-3200,但在使用兩個(gè)內(nèi)存通道時(shí),我們無(wú)法以3200的速度穩(wěn)定啟動(dòng)(譯者注:龍芯的CPU和主板對(duì)內(nèi)存的兼容性不如Intel和AMD,但整機(jī)配套的以及經(jīng)銷商推薦的型號(hào)都是經(jīng)過(guò)測(cè)試驗(yàn)證的)。當(dāng)配備雙通道DDR4-2666時(shí),3A6000實(shí)現(xiàn)的DRAM讀取帶寬大致與Core i5-6600K不相上下。該芯片的第一代DDR4控制器只能以完美的穩(wěn)定性使用DDR4-2133(至少我得到的樣品是這樣),但與具有更快內(nèi)存的3A6000相比,它具有更好的DRAM讀取帶寬。
盡管3A6000的DRAM讀取性能平平,但它在寫入方面確實(shí)有訣竅。當(dāng)龍芯檢測(cè)到緩存被覆蓋而不依賴于其先前的內(nèi)容時(shí),它可能會(huì)避免讀取訪問(wèn)請(qǐng)求。這可能有助于某些訪問(wèn)模式,但好處可能有限,因?yàn)槌绦虻淖x取量往往遠(yuǎn)遠(yuǎn)多于寫入量。
十二、核心到核心延遲(Core to Core Latency)
這項(xiàng)測(cè)試使用原子指令的比較和交換操作,獲得每個(gè)核心之間信號(hào)反彈的時(shí)間。
龍芯3A6000的表現(xiàn)沒(méi)有帶來(lái)任何驚喜,但這是一件好事。
十三、結(jié)束語(yǔ)(Final Words)
龍芯的工程師們有很多值得驕傲的地方。創(chuàng)建一個(gè)與Zen 2類似的分支預(yù)測(cè)器并不容易,考慮到龍芯在3A5000中的表現(xiàn),這一成就更加令人印象深刻。同樣,SMT也很難做好,龍芯成功地做到了這兩件事。同時(shí)龍芯大幅擴(kuò)大了亂序執(zhí)行的規(guī)模,并改善了其DDR4控制器的性能。由此帶來(lái)的巨大性能提升使基于LA664的3A6000與主頻4.0GHz左右的Zen 1架構(gòu)的CPU不相上下,至少當(dāng)物理核心的數(shù)量相同時(shí)是這樣。
中國(guó)在努力減少經(jīng)濟(jì)發(fā)展依賴外國(guó)CPU的情況,3A6000是努力的一部分。在減少對(duì)外國(guó)依賴這方面,3A6000是向前邁出的一大步。Zen 1在今天仍然很實(shí)用,所以中國(guó)消費(fèi)者可能會(huì)發(fā)現(xiàn)3A6000的性能對(duì)于輕量級(jí)的日常任務(wù)來(lái)說(shuō)是可以接受的。龍芯的軟件生態(tài)系統(tǒng)對(duì)芯片可用性的影響將遠(yuǎn)遠(yuǎn)大于其性能。
但龍芯的次要目標(biāo)是與Intel和AMD等西方公司一起成為世界級(jí)的CPU制造商。在這方面,他們還有很長(zhǎng)的路要走。Zen 1級(jí)單核性能值得稱贊,但我們必須記住,Zen 1在與英特爾的競(jìng)爭(zhēng)中獲得了市場(chǎng)份額,是因?yàn)樗鼘r(jià)格合理的6核和8核產(chǎn)品帶入了消費(fèi)者平臺(tái),而不是因?yàn)樗梢栽谂cSkylake的競(jìng)爭(zhēng)中贏得核心對(duì)核心的勝利。3A6000只是一個(gè)四核產(chǎn)品,因此缺乏Zen 1最大的優(yōu)勢(shì)。
龍芯還將3A6000與英特爾的酷睿i3-10100進(jìn)行了比較,后者是一款四核Skylake產(chǎn)品,具有6 MB的緩存和4.3 GHz的睿頻。雖然名義上是第10代部件,但i3-10100與2015年的酷睿i7-6700K(譯者注:i7-6700K是6代酷睿的最高端型號(hào))更具可比性。英特爾的第10代更廣為人知的是,它將10核CPU納入了公司的消費(fèi)級(jí)產(chǎn)品陣容,其中6核和8核產(chǎn)品構(gòu)成了中端產(chǎn)品。除了更多的核心之外,i5-10600K和i7-10700K等部件還具有更高的睿頻。3A6000將無(wú)法與這些產(chǎn)品競(jìng)爭(zhēng)。龍芯還將與Zen 2作斗爭(zhēng),我們已經(jīng)看到3950X在核心對(duì)核心的測(cè)試中戰(zhàn)勝了3A6000,但只有當(dāng)超過(guò)四個(gè)Zen 2核心發(fā)揮作用時(shí),這種差距才會(huì)擴(kuò)大。
如今,英特爾的Golden Cove衍生產(chǎn)品和AMD的Zen 4比3A6000的優(yōu)勢(shì)更大。AMD和英特爾的消費(fèi)級(jí)產(chǎn)品陣容中基本上都沒(méi)有四核產(chǎn)品。龍芯的3A6000可能是我們?cè)谥袊?guó)看到的最有前途的CPU,它比迭代ARM A72的拙劣嘗試更令人興奮。但龍芯的工程師們?nèi)杂泄ぷ饕?,我們期待著看到他們下一步的表現(xiàn)。
評(píng)論