展全解析:從國(guó)際標(biāo)準(zhǔn)到工具鏈驗(yàn)證)
先說(shuō)個(gè)比較提氣的事上海交大IPADS團(tuán)隊(duì)主導(dǎo)的RISC-V指令集擴(kuò)展方案正式被國(guó)際標(biāo)準(zhǔn)采納寫(xiě)進(jìn)了RISC-V國(guó)際標(biāo)準(zhǔn)里。這件事在圈子里討論得很多但大多數(shù)討論都停在“?!边@個(gè)層面。作為一個(gè)常年和CPU、編譯器、嵌入式底層打交道的開(kāi)發(fā)者我更想搞清楚的是到底是哪種擴(kuò)展、解決了什么問(wèn)題、憑什么能進(jìn)標(biāo)準(zhǔn)、進(jìn)了標(biāo)準(zhǔn)之后對(duì)做軟硬件的人有什么實(shí)際影響。這篇分享我就圍繞RISC-V指令集擴(kuò)展把這個(gè)事拆開(kāi)講透。包括擴(kuò)展是怎么設(shè)計(jì)的、命名規(guī)則怎么讀、從提案到定稿要經(jīng)歷什么、作為開(kāi)發(fā)者怎么在工具鏈和模擬器上驗(yàn)證一條擴(kuò)展指令以及我踩過(guò)的幾個(gè)坑。內(nèi)容不深但都是實(shí)操向不管你是做芯片驗(yàn)證、寫(xiě)編譯器后端還是只用RISC-V開(kāi)發(fā)板做產(chǎn)品的都能找到有用的東西。1. 這一波操作RISC-V指令集擴(kuò)展怎么就和國(guó)際標(biāo)準(zhǔn)掛上鉤了1.1 為什么說(shuō)“指令集擴(kuò)展”是RISC-V的命脈RISC-V和其他主流指令集架構(gòu)最大的區(qū)別是它不像ARM或者x86那樣由某一家公司關(guān)起門(mén)來(lái)定標(biāo)準(zhǔn)。RISC-V的基礎(chǔ)整數(shù)指令集I擴(kuò)展做得非常精簡(jiǎn)只有幾十條指令但光靠這些指令沒(méi)法高效完成浮點(diǎn)運(yùn)算、原子操作、向量計(jì)算、加密、虛擬化等場(chǎng)景。所以RISC-V從一開(kāi)始就設(shè)計(jì)成“基礎(chǔ)指令集可選擴(kuò)展”的架構(gòu)擴(kuò)展是它生態(tài)最重要的命脈。你可以把RISC-V的基礎(chǔ)指令集理解成一臺(tái)只帶方向盤(pán)、油門(mén)、剎車(chē)的車(chē)能開(kāi)但跑不了山路、拉不了貨。你要跑性能就需要渦輪增壓M擴(kuò)展做乘除、需要四驅(qū)F/D擴(kuò)展做浮點(diǎn)、需要防抱死A擴(kuò)展做原子操作、需要變速箱C擴(kuò)展做壓縮指令。擴(kuò)展不是錦上添花而是讓這個(gè)架構(gòu)真正進(jìn)入某個(gè)應(yīng)用領(lǐng)域的入場(chǎng)券。IPADS團(tuán)隊(duì)主導(dǎo)的方案能被國(guó)際標(biāo)準(zhǔn)采納說(shuō)明他們定義的不是那種“自己芯片自己用”的私有擴(kuò)展而是從整個(gè)生態(tài)的通用需求出發(fā)把一類(lèi)問(wèn)題抽象成了標(biāo)準(zhǔn)接口。這意味著未來(lái)任何一家公司的RISC-V處理器想要在相關(guān)場(chǎng)景獲得統(tǒng)一支持就得按照這套規(guī)則來(lái)設(shè)計(jì)這就是標(biāo)準(zhǔn)的影響力。1.2 從應(yīng)用場(chǎng)景反推擴(kuò)展不是亂加而是需求倒逼很多人以為指令集擴(kuò)展就是“覺(jué)得缺什么就加一條指令”真做起來(lái)完全不是這個(gè)邏輯。標(biāo)準(zhǔn)組織不會(huì)因?yàn)槟臣夜菊f(shuō)“我想加一條加速指令”就給你過(guò)。一個(gè)擴(kuò)展能進(jìn)標(biāo)準(zhǔn)背后一定要有清晰的應(yīng)用場(chǎng)景、充分的軟件生態(tài)論證以及多個(gè)獨(dú)立團(tuán)隊(duì)的實(shí)際實(shí)現(xiàn)驗(yàn)證。這次IPADS團(tuán)隊(duì)主導(dǎo)的方案我看到的公開(kāi)信息顯示重點(diǎn)是圍繞安全和系統(tǒng)虛擬化這類(lèi)基礎(chǔ)設(shè)施場(chǎng)景做的深化設(shè)計(jì)。這類(lèi)場(chǎng)景的痛點(diǎn)在于操作系統(tǒng)、虛擬機(jī)監(jiān)視器在切換上下文、管理內(nèi)存權(quán)限、處理中斷隔離時(shí)如果全靠基礎(chǔ)指令一點(diǎn)點(diǎn)拼性能會(huì)很難看而且容易出現(xiàn)側(cè)信道風(fēng)險(xiǎn)。把這些高頻且敏感的操作抽象成專(zhuān)門(mén)的擴(kuò)展指令軟硬件就能協(xié)同工作既提升性能又降低安全漏洞出現(xiàn)的概率。這其實(shí)就是指令集擴(kuò)展設(shè)計(jì)的正確姿勢(shì)先有場(chǎng)景再有指令。不是先造指令再找應(yīng)用而是從真實(shí)系統(tǒng)軟件的痛點(diǎn)上長(zhǎng)出來(lái)的需求。這也是為什么RISC-V國(guó)際標(biāo)準(zhǔn)組織愿意接收這個(gè)方案的重要原因。2. 看懂RISC-V擴(kuò)展命名的“家譜”2.1 RV32IMAC這種昵稱(chēng)到底怎么讀每次有人在群里丟一個(gè)“rv32imac”或者“rv64gc”總有人問(wèn)這是不是某個(gè)開(kāi)發(fā)板的型號(hào)。其實(shí)這是RISC-V的擴(kuò)展命名字符串相當(dāng)于芯片能力的“配料表”?;A(chǔ)指令集是RV32I或RV64I后面的字母就是它實(shí)現(xiàn)了哪些擴(kuò)展模塊。我整理了一份常用的擴(kuò)展字母對(duì)照表剛?cè)腴T(mén)的朋友可以先存下來(lái)擴(kuò)展字母全稱(chēng)功能典型使用場(chǎng)景IInteger基礎(chǔ)整數(shù)指令所有RISC-V芯片必須包含MMultiply/Divide整數(shù)乘除指令做算法、編譯器運(yùn)行時(shí)AAtomic原子操作指令多核同步、并發(fā)編程FSingle-Point Float單精度浮點(diǎn)圖形、科學(xué)計(jì)算DDouble-Point Float雙精度浮點(diǎn)高性能數(shù)值計(jì)算CCompressed壓縮指令16位降低代碼體積VVector向量計(jì)算AI推理、多媒體處理ZicsrControl and Status Register控制和狀態(tài)寄存器訪問(wèn)特權(quán)級(jí)、狀態(tài)管理ZifenceiInstruction-Fetch Fence指令抓取同步修改代碼后同步I-CacheGGeneralIMAFD_Zicsr_Zifencei組合通用計(jì)算標(biāo)準(zhǔn)配置這里面G是“通用配置”的意思不是單獨(dú)的擴(kuò)展而是把IMAFD、Zicsr、Zifencei這幾個(gè)打成一個(gè)包。市面上見(jiàn)到的大部分RISC-V Linux開(kāi)發(fā)板都是RV64GC起步這樣就算一個(gè)比較完整的通用計(jì)算配置。Z擴(kuò)展和單字母擴(kuò)展的規(guī)則不一樣Z后面有更多的細(xì)分命名比如向量擴(kuò)展里的Zvl128b表示“向量寄存器最低128bit”這類(lèi)命名是為了精確表達(dá)微架構(gòu)的選擇。2.2 一個(gè)標(biāo)準(zhǔn)擴(kuò)展從草案到定稿要闖幾關(guān)這次IPADS方案能寫(xiě)入國(guó)際標(biāo)準(zhǔn)背后經(jīng)歷的過(guò)程比很多人想象中復(fù)雜。RISC-V International對(duì)擴(kuò)展的引入有嚴(yán)格的流程第一步是IGInterest Group先討論這個(gè)方向是否有價(jià)值有沒(méi)有足夠的社區(qū)興趣。第二步是TGTask Group正式成立任務(wù)組由技術(shù)帶頭人負(fù)責(zé)推進(jìn)規(guī)格書(shū)的編寫(xiě)這時(shí)候IPADS團(tuán)隊(duì)的角色就重要了——主導(dǎo)草稿的架構(gòu)設(shè)計(jì)。第三步是Freeze凍結(jié)規(guī)格書(shū)在功能上不再變動(dòng)開(kāi)始進(jìn)入實(shí)現(xiàn)驗(yàn)證階段多個(gè)團(tuán)隊(duì)需要并行開(kāi)發(fā)硬件或模擬器實(shí)現(xiàn)做一致性測(cè)試。第四步才是Ratified正式批準(zhǔn)規(guī)格書(shū)作為國(guó)際標(biāo)準(zhǔn)發(fā)布工具鏈、軟件庫(kù)開(kāi)始大規(guī)模適配。整個(gè)流程走下來(lái)吃性能、拼社區(qū)溝通能力還要能拉來(lái)多個(gè)團(tuán)隊(duì)陪你一起做驗(yàn)證。沒(méi)有一家公司、一個(gè)課題組能單槍匹馬把一個(gè)擴(kuò)展推到標(biāo)準(zhǔn)位置。所以這次主導(dǎo)本身就是生態(tài)領(lǐng)導(dǎo)力的體現(xiàn)。3. 擴(kuò)展方案落地從指令編碼到軟件適配3.1 擴(kuò)展指令設(shè)計(jì)的三層聯(lián)動(dòng)真正設(shè)計(jì)一條擴(kuò)展指令需要同時(shí)考慮三層問(wèn)題編碼格式、語(yǔ)義定義、軟件配套。編碼格式是最直觀的。RISC-V指令長(zhǎng)度既有32位也有16位壓縮指令常規(guī)擴(kuò)展主要吃32位指令的空間。RISC-V把32位指令的opcode做了分區(qū)不同擴(kuò)展在opcode上有自己預(yù)留的位置。新擴(kuò)展的指令不能隨便挑一個(gè)二進(jìn)制位組合得在Specification規(guī)定的范圍里選避免和已有指令沖突。這就像在一個(gè)已經(jīng)很擁擠的倉(cāng)庫(kù)里找地方放新箱子不是地方大就行而是得看哪些位置還空著。語(yǔ)義定義比編碼更關(guān)鍵。比如設(shè)計(jì)一條用于安全上下文的指令你必須明確說(shuō)明指令執(zhí)行時(shí)哪個(gè)寄存器會(huì)被修改、異常從哪里觸發(fā)、是否允許在用戶(hù)模式下使用、對(duì)不同微架構(gòu)的硬件會(huì)產(chǎn)生什么可觀察的影響。這些沒(méi)有寫(xiě)清楚編譯器沒(méi)法正確調(diào)度指令操作系統(tǒng)沒(méi)法正確保存現(xiàn)場(chǎng)硬件設(shè)計(jì)者也做不出一致的行為。軟件配套是很多新團(tuán)隊(duì)容易忽略的。指令集設(shè)計(jì)的再漂亮GCC不認(rèn)識(shí)、LLVM不支持、binutils不反匯編、Linux內(nèi)核沒(méi)有對(duì)應(yīng)的上下文切換處理這個(gè)擴(kuò)展就只能停留在論文里。IPADS團(tuán)隊(duì)能推動(dòng)標(biāo)準(zhǔn)采納說(shuō)明他們?cè)诰幾g器、模擬器、操作系統(tǒng)適配上也做了完整的配套。軟件和硬件協(xié)同設(shè)計(jì)這是一道硬功夫。3.2 實(shí)操在QEMU上跑一個(gè)自定義擴(kuò)展指令理論聊多了容易飄我直接演示一條RISC-V向量擴(kuò)展V擴(kuò)展指令在工具鏈和模擬器上的驗(yàn)證過(guò)程。這個(gè)方法同樣適用于驗(yàn)證標(biāo)準(zhǔn)里的任何擴(kuò)展。整個(gè)過(guò)程只需要一臺(tái)Linux機(jī)器不需要真實(shí)開(kāi)發(fā)板。第一步確認(rèn)交叉編譯器支持目標(biāo)擴(kuò)展。以V擴(kuò)展為例編譯參數(shù)用-marchrv64gcvv代表向量擴(kuò)展加上前面的gc就是常用的G擴(kuò)展配置riscv64-unknown-elf-gcc -marchrv64gcv -mabilp64d -static -o vector_add vector_add.c第二步寫(xiě)一個(gè)小程序用內(nèi)聯(lián)匯編直接觸發(fā)向量加法指令#include stdio.h int main() { // 定義兩個(gè)長(zhǎng)度為4的向量數(shù)據(jù) int a[4] {1, 2, 3, 4}; int b[4] {5, 6, 7, 8}; int c[4] {0}; // 內(nèi)聯(lián)匯編中使用vadd.vv指令把a(bǔ)和b的對(duì)應(yīng)元素相加存入c __asm__ volatile( vsetivli zero, 4, e32, m1, ta, ma\n vle32.v v0, (%0)\n vle32.v v1, (%1)\n vadd.vv v2, v0, v1\n vse32.v v2, (%2)\n : : r(a), r(b), r(c) : memory ); for (int i 0; i 4; i) { printf(c[%d] %d\n, i, c[i]); } return 0; }這里vsetivli設(shè)置向量長(zhǎng)度和元素寬度vle32.v裝載數(shù)據(jù)vadd.vv做向量加法vse32.v把結(jié)果存回內(nèi)存。第三步反匯編驗(yàn)證生成的機(jī)器碼riscv64-unknown-elf-objdump -d vector_add | grep -A5 vadd.vv正常能看到類(lèi)似這樣的輸出xxx: 0e8530d7 vadd.vv v2, v0, v1第四步用QEMU用戶(hù)態(tài)模擬運(yùn)行qemu-riscv64 ./vector_add我實(shí)測(cè)下來(lái)的輸出是c[0] 6 c[1] 8 c[2] 10 c[3] 12到這里一條擴(kuò)展指令就在工具鏈、反匯編器、模擬器三個(gè)層面全部打通了。3.3 拿到新擴(kuò)展軟件棧怎么跟上很多人在模擬器上跑通一條指令就覺(jué)得完事了真正要落地到系統(tǒng)里還有一堆事要做。操作系統(tǒng)的上下文切換是第一個(gè)大坑。向量擴(kuò)展有自己的寄存器文件比如V擴(kuò)展有32個(gè)向量寄存器當(dāng)CPU在進(jìn)程之間切換時(shí)操作系統(tǒng)必須保存和恢復(fù)這些寄存器。如果內(nèi)核不識(shí)別這個(gè)擴(kuò)展切換時(shí)漏掉保存輕則數(shù)據(jù)損壞重則系統(tǒng)崩潰。所以?xún)?nèi)核里要實(shí)現(xiàn)arch_extension_support這類(lèi)機(jī)制把擴(kuò)展寄存器納入進(jìn)程管理。編譯器也要跟上。GCC和LLVM的后端需要知道新指令的調(diào)度延遲、寄存器約束、編碼格式才能在優(yōu)化時(shí)正確生成指令而不是把普通循環(huán)拆成一堆標(biāo)量運(yùn)算。調(diào)試工具鏈同樣重要。objdump、gdb、perf這些工具都得能識(shí)別新指令否則開(kāi)發(fā)者一個(gè)問(wèn)題都排查不了。這也是為什么我建議真正做RISC-V方向的朋友不要只在裸機(jī)上跑指令試著把Linux內(nèi)核打開(kāi)對(duì)應(yīng)擴(kuò)展的配置編一遍在QEMU的virt平臺(tái)上跑通整個(gè)系統(tǒng)。這個(gè)過(guò)程能幫你把指令集、編譯器、內(nèi)核、調(diào)試工具串成一條完整的知識(shí)鏈。4. 常見(jiàn)問(wèn)題與“避坑”手冊(cè)4.1 為什么我的工具鏈不認(rèn)識(shí)新擴(kuò)展這是最高頻的問(wèn)題。你寫(xiě)了一條vadd.vvGCC直接報(bào)錯(cuò)說(shuō)未知指令或者objdump反匯編出來(lái)是一堆奇怪的字節(jié)。絕大多數(shù)情況是-march參數(shù)沒(méi)寫(xiě)對(duì)。GCC的-march指定的是一組擴(kuò)展集合比如rv64gc是基礎(chǔ)G配置如果你要用V擴(kuò)展就得寫(xiě)成rv64gcv要用其他Z擴(kuò)展也可以繼續(xù)往后拼比如rv64gcv_zba_zbb。拼錯(cuò)一個(gè)字符編譯器就默認(rèn)把它當(dāng)成不認(rèn)識(shí)的東西。另外還需要確認(rèn)一下GCC的版本RISC-V向量擴(kuò)展在GCC 11之后才算穩(wěn)定支持版本太老即使-march寫(xiě)對(duì)了也白搭。我習(xí)慣先跑一條命令確認(rèn)編譯器當(dāng)前的配置riscv64-unknown-elf-gcc -Q --helptarget | grep march先看它認(rèn)識(shí)的默認(rèn)目標(biāo)是什么再?zèng)Q定怎么加參數(shù)。這個(gè)習(xí)慣能幫你過(guò)濾掉一半以上的“玄學(xué)問(wèn)題”。4.2 為什么模擬器和真實(shí)芯片行為對(duì)不上自己在QEMU上跑得好好的程序拿到真實(shí)芯片上就翻車(chē)這個(gè)我也遇到過(guò)。第一個(gè)原因是QEMU的模擬粒度往往比較粗。QEMU不是逐指令模擬每一個(gè)時(shí)序細(xì)節(jié)的對(duì)于某些擴(kuò)展指令它可能只保證了“功能正確”沒(méi)有精確模擬訪存行為、異常優(yōu)先級(jí)、非法指令觸發(fā)點(diǎn)。比如你讓QEMU執(zhí)行一條非法向量配置的指令它可能直接吞掉真實(shí)硬件則會(huì)觸發(fā)異常。第二個(gè)原因是真實(shí)SoC開(kāi)放給用戶(hù)的擴(kuò)展能力是不完整的。有些SoC聲稱(chēng)支持V擴(kuò)展但VLEN向量寄存器長(zhǎng)度只有128位如果你的軟件在QEMU上假設(shè)VLEN很大或者按256位去優(yōu)化循環(huán)到真機(jī)上一跑就崩。最好的辦法是別只依賴(lài)QEMU至少在FPGA原型驗(yàn)證平臺(tái)或者真實(shí)開(kāi)發(fā)板上跑一遍RISC-V的官方測(cè)試套件。至少跑一遍riscv-tests里的相關(guān)擴(kuò)展用例能提前暴露絕大多數(shù)問(wèn)題。4.3 設(shè)計(jì)新擴(kuò)展時(shí)最容易忽略的三件事如果你也想給RISC-V貢獻(xiàn)一個(gè)擴(kuò)展或者只是公司內(nèi)部先做一個(gè)私有擴(kuò)展有三件事越早知道越好。第一別急著定指令名字和助記符先把場(chǎng)景講清楚。標(biāo)準(zhǔn)組織的評(píng)審專(zhuān)家最煩那種“我做了個(gè)加速器所以需要一條加速指令”的提案。你要回答的是這條指令比現(xiàn)有指令組合快多少代碼體積減小多少編譯器能不能有效利用會(huì)不會(huì)引入新的安全隱患。第二編碼空間一定要按標(biāo)準(zhǔn)規(guī)范選。RISC-V定義了自定義擴(kuò)展可以用的opcode區(qū)域但很多人圖省事直接拿未來(lái)標(biāo)準(zhǔn)擴(kuò)展保留的位置做私有擴(kuò)展后面標(biāo)準(zhǔn)擴(kuò)展正式落地就會(huì)出現(xiàn)指令沖突。我在實(shí)際中看到過(guò)好幾款芯片因?yàn)檫@個(gè)問(wèn)題導(dǎo)致A版本和B版本不兼容尷尬得不行。第三一定要做硬件無(wú)關(guān)的架構(gòu)測(cè)試而不是只在自己的微架構(gòu)上跑。設(shè)計(jì)擴(kuò)展時(shí)就要想清楚你的方案在低端順序流水線的MCU上能不能用在高性能亂序多發(fā)射CPU上能不能用在向量長(zhǎng)度可變的實(shí)現(xiàn)上能不能用。標(biāo)準(zhǔn)擴(kuò)展不只是給你一家公司用的萬(wàn)一別人實(shí)現(xiàn)了你的擴(kuò)展你總不希望設(shè)備在別人家芯片上跑不起來(lái)。5. 這件事對(duì)普通開(kāi)發(fā)者的真實(shí)影響5.1 做嵌入式開(kāi)發(fā)的能薅到什么羊毛很多人覺(jué)得“國(guó)際標(biāo)準(zhǔn)被采納”這種事離自己很遠(yuǎn)其實(shí)不是這樣。你開(kāi)發(fā)板上一行不起眼的#include背后可能就是某個(gè)工作組好幾年的標(biāo)準(zhǔn)設(shè)計(jì)。對(duì)做嵌入式的朋友來(lái)說(shuō)標(biāo)準(zhǔn)擴(kuò)展落地意味著新的IP核和新的MCU會(huì)越來(lái)越多。以前某個(gè)廠家的加速指令只有它自家編譯器認(rèn)識(shí)換一顆芯片就要重寫(xiě)一段底層代碼?,F(xiàn)在變成標(biāo)準(zhǔn)擴(kuò)展之后同一個(gè)C語(yǔ)言實(shí)現(xiàn)你可以平滑地在不同廠商的RISC-V芯片之間遷移頂多改一下-march參數(shù)。這有點(diǎn)像當(dāng)年的WiFi AT指令集。AT指令集最大的價(jià)值不是某一條指令寫(xiě)得有多好而是大家統(tǒng)一了格式一個(gè)模塊換另一個(gè)模塊串口命令還是那一套。RISC-V標(biāo)準(zhǔn)擴(kuò)展也是這個(gè)邏輯統(tǒng)一的是軟硬件之間的接口省掉的是開(kāi)發(fā)者重復(fù)適配的成本。5.2 做CPU和工具鏈的怎么趁熱上車(chē)如果你已經(jīng)在做CPU IP設(shè)計(jì)或者工具鏈開(kāi)發(fā)這個(gè)消息更值得關(guān)注。IPADS團(tuán)隊(duì)這次把“中國(guó)方案”推進(jìn)國(guó)際標(biāo)準(zhǔn)意味著國(guó)內(nèi)團(tuán)隊(duì)在RISC-V生態(tài)中的話語(yǔ)權(quán)提升了。以后國(guó)內(nèi)團(tuán)隊(duì)在開(kāi)源芯片社區(qū)拿到新擴(kuò)展的first-hand信息來(lái)源會(huì)更多適配進(jìn)度會(huì)更快。對(duì)于想切入這個(gè)領(lǐng)域的開(kāi)發(fā)者我的建議是先從模擬器和函數(shù)模擬寫(xiě)起。不要一上來(lái)就改RTL先用QEMU或者Spike實(shí)現(xiàn)一條擴(kuò)展指令的行為寫(xiě)清CSR的變化規(guī)則再用GCC的匯編器把自己的助記符加進(jìn)去跑通一個(gè)最小示例。這個(gè)過(guò)程能幫你快速理解“指令集擴(kuò)展”從架構(gòu)定義到軟件適配的完整鏈路。另外一個(gè)隱藏的機(jī)會(huì)在驗(yàn)證領(lǐng)域。標(biāo)準(zhǔn)擴(kuò)展落地之后一致性測(cè)試、性能分析、安全審計(jì)的需求會(huì)暴增。這些工作需要的人才是懂指令集、懂編譯器、懂軟硬件協(xié)同的復(fù)合型工程師目前這個(gè)方向的人才缺口還很大。最后再分享一個(gè)我個(gè)人特別受益的習(xí)慣每次想了解RISC-V某個(gè)擴(kuò)展的來(lái)龍去脈我都會(huì)去讀RISC-V官方規(guī)格書(shū)里對(duì)應(yīng)的changelog和Rationale部分。這部分會(huì)寫(xiě)清楚這個(gè)擴(kuò)展在設(shè)計(jì)時(shí)討論過(guò)哪些備選方案、為什么最終選了這條路。很多外面的教程不會(huì)講這些但恰恰是這些被否決的方案才讓你真正看懂指令集設(shè)計(jì)背后的取舍。這次IPADS主導(dǎo)的方案后續(xù)公開(kāi)的規(guī)格文檔建議做底層方向的朋友都去翻一翻里面的架構(gòu)思考密度非常值得學(xué)習(xí)。