首頁>科技>

蘋果晶片正在快速崛起。無論是從配置還是從其他方面,蘋果在超越自己的同時也遠遠地把同行甩在後面。本文將詳細解答:為什麼蘋果的 M1 執行速度會如此之快?

我透過 YouTube 上的一個影片看到一位 Mac 使用者在去年購買了一臺 iMac。這臺 4000 美元的電腦配置了最大的 40GB 記憶體。然而後來,他難以置信地看著自己花斥資購買的 iMac 被新型的 M1 Mac Mini 打敗,而這臺裝置僅花了約 700 美元。

在現實世界一次又一次的測試中,M1 Macs 不僅超越了頂配的英特爾 Mac,而且還徹底擊垮了這些電腦。很多人都覺得不可思議,他們開始探究這到底是怎麼回事。

如果你也持有這樣的疑問,那麼你來對地方了。在本文中,我將深度剖析蘋果的 M1 晶片。具體來說,我認為很多人都持有以下疑問:

從技術的角度來看,為什麼 M1 晶片會如此之快?蘋果是否採用了一些非同尋常的技術?對於英特爾和 AMD 等競爭對手來說,採用相同的技術是否也很容易?

當然,你可以在網上搜索這些問題的答案,但如果你想深入瞭解蘋果所做出的努力,那麼可能很快就會被高度專業的技術術語淹沒。例如 M1 使用了非常寬的指令解碼器、巨大的重排序緩衝區(ROB)等等。除非你非常瞭解 CPU 硬體,否則大多數文章對你來說都是天書。

為了方便理解,下面我來簡要介紹一下有關 M1 晶片的基礎知識。

什麼是微處理器(CPU)?

通常,我們談論的英特爾與 AMD 晶片指的都是中央處理器(CPU),或稱微處理器。這些晶片從記憶體獲取指令,然後按照順序執行每條指令。

圖:一個非常基本的 RISC CPU(不是 M1)

指令從儲存器(memory)沿藍色箭頭移動到指令暫存器(register),然後由解碼器(decoder)解析指令,並透過紅色控制線啟動CPU的不同部分,最後由運算器(ALU)將暫存器中的數字相加或相減。

最基本的CPU包含一系列暫存器(register)和若干運算器(ALU),其中暫存器是命名的儲存單元,而運算器則是計算單元。ALU 可以執行加法、減法以及其他基本數學運算之類的操作。但是,ALU 只連線到 CPU 暫存器。如果要想執行兩個數字相加的運算,則必須從記憶體中獲取這兩個數字並放入 CPU 的兩個暫存器中。

以下是 M1 上的 RISC CPU 執行的一些常見的指令示例:

load r1, 15load r2, 200add  r1, r2store r1, 310

上述 r1 和 r2 就是我們所說的暫存器。現代 RISC CPU 無法針對位於暫存器之外的數字進行這樣的操作。例如,它不能將記憶體中兩個不同位置的數字相加。相反,它必須將這兩個數字放入單獨的暫存器中。這就是上述示例中的前兩條指令。我們從記憶體地址 150 中提取數字,並將其放入 CPU 的暫存器 r1 中。接下來,我們將地址 200 中的數字放入暫存器 r2 中。只有這樣,兩個數字才能透過指令 add r1,r2 相加。

圖:一臺舊式機械計算器

擁有兩個暫存器、累加器和輸入暫存器。現代 CPU 通常擁有十幾個暫存器,而且是電子的。

暫存器的概念很早以前就有了。例如,在上圖的舊式機械計算器中,暫存器是儲存兩個加數的地方。暫存器就是存放數字的地方。

M1 不是 CPU!

瞭解 M1 的時候,需要注意一點:

M1 不是 CPU它是一個集成了多個晶片的整體系統。而 CPU 只是其中一個晶片。

簡單來說,M1 就是將一臺完整的計算機整合到了一個晶片上。M1 包含 CPU、圖形處理單元(GPU)、記憶體、輸入和輸出控制器以及構成一臺整體計算機的許多其他元件。這就是我們所說的單片系統(System on a Chip,即SoC)。

如今,購買英特爾或 AMD 的晶片時,實際上你得到的是一個封裝了多個微處理器的晶片。過去,計算機的諸多晶片會分散載入到主機板上。

圖:計算機主機板示例

記憶體、CPU、顯示卡、IO 控制器、網絡卡以及許多其他元件都連線到了主機板上,可以相互通訊。

然而,由於如今我們能夠在一塊矽片上放置非常多的電晶體,因此英特爾和AMD等公司紛紛開始將多個微處理器整合到一個晶片上。我們稱這些晶片為CPU核心。一個核心基本上就是一個完全獨立的晶片,可以從記憶體中讀取指令並執行計算。

圖:擁有多個CPU核心的微晶片

長期以來,要想提高效能,只需新增更多通用 CPU 核心即可。然而,如今情況發生了變化,CPU 市場的一位商家開始偏離這種趨勢。

蘋果的異構計算策略並沒有那麼神秘

蘋果並沒有選擇增加通用 CPU 核心,他們採取了另一種策略:新增越來越多專用晶片來完成一些專門的任務。這樣做的好處是,與通用 CPU 核心相比,專用晶片能夠更快地完成任務,而且耗電量更少。

這不是一個全新的做法。多年來,英偉達和 AMD 的顯示卡中都搭載了圖形處理單元(GPU)等專用晶片,這些晶片執行與圖形相關的操作要比通用 CPU 快許多。

蘋果所做的只是更大膽地朝這個方向轉變。M1 不僅具有通用核心和儲存器,而且還包含各種專用晶片:

中央處理單元(CPU):單片系統的大腦。負責執行作業系統和應用程式的大多數程式碼。圖形處理單元(GPU):處理與圖形相關的任務。例如顯示應用程式的使用者介面,以及 2D/3D 遊戲等。影象處理單元(ISP):可用於加速影象處理應用程式的常見任務。數字訊號處理器(DSP):能夠比 CPU 更好地處理需要大量數學運算的任務。包括解壓縮音樂檔案等。神經處理單元(NPU):用於高階智慧手機,可加速機器學習(AI)任務。包括語音識別和相機處理。影片編碼器/解碼器:處理影片檔案和格式的轉換,且耗能更低。安全領域:加密、身份認證以及安全性。統一記憶體:允許 CPU、GPU 和其他核心快速交換資訊。

這就是為什麼許多人在使用 M1 Mac 進行影象和影片編輯時,都能看到速度提升的部分原因。他們執行的許多工可以直接在專用硬體上執行。因此,價格低廉的 M1 Mac Mini 輕而易舉就能夠編碼大型影片檔案,而昂貴的 iMac 即便所有風扇都全力運轉也趕不上。

在藍色區域內,你可以看到多個 CPU 核心可以同時訪問記憶體,而在綠色框內,大量 GPU 核心在訪問記憶體。

你可能不太理解統一記憶體。共享記憶體與統一記憶體有何不同?過去,人們不是不贊成影片記憶體與主記憶體共享嗎?因為這會導致效能降低。的確,共享記憶體確實不好。原因是 CPU 和 GPU 必須輪流訪問記憶體。共享意味著二者要爭用資料匯流排。簡單來說,GPU 和 CPU 必須輪流使用狹窄的管道來儲存或提取資料。

但統一記憶體的情況不一樣。在統一記憶體中,GPU 核心和 CPU 核心可以同時訪問記憶體。因此,共享記憶體沒有額外開銷。另外,CPU 和 GPU 可以互相通知資料在記憶體中的位置。以前,CPU 必須將資料從主記憶體區域複製到 GPU 使用的區域。但在統一記憶體中,CPU 會告知 GPU:“我從記憶體地址 2430 開始放置了30MB 的多邊形資料。”而 GPU 無需複製就可以使用這段記憶體。

這意味著,由於 M1 上各種特殊的處理器都可以使用相同的記憶體池,並快速交換資訊,因此可以大幅提升效能。

在統一記憶體出現之前,Mac 使用 GPU 的方式。你甚至可以選用計算機外部安裝的顯示卡(透過 Thunderbolt 3 線安裝)。有人猜測未來這種情況仍有可能出現。

為什麼英特爾和 AMD 不使用相同的戰略?

既然蘋果的做法如此聰明,為何大家不照搬呢?從某種程度上來說,有些人確實在照抄蘋果。有些 ARM 晶片製造商在專用硬體上的投資越來越多。

AMD還嘗試在某些晶片上安裝功能更強大的GPU,並逐步採用加速處理單元(APU),向著單片系統邁進,這些處理器的CPU核心和GPU核心基本上都位於同一個晶片之上。

AMD Ryzen 加速處理單元(APU)在一塊晶片上集成了 CPU 和 GPU(Radeon Vega)。但是不包含其他協同處理器、IO 控制器或統一記憶體。

然而,還有一些重要的原因致使他們無法完全貫徹蘋果的做法。單片系統本質上是在一塊晶片上構建整個計算機。因此,這種做法更適合於真正的計算機制造商,比如惠普和戴爾等。我用汽車來做一個簡單的類比:如果你的業務模型是製造和銷售汽車發動機,那麼對你來說,製造和銷售整車將是一次不尋常的飛躍。

相比之下,這對於 ARM 來說並不是大問題。戴爾或惠普等計算機制造商只需要購買 ARM 和其他廠商晶片的授權,就可以利用各種專用硬體製作自己的單片系統。接下來,他們將完成的設計移交給 GlobalFoundries 或臺積電等半導體代工廠,這些工廠如今就在為 AMD 和蘋果生產晶片。

圖:臺積電半導體代工廠,負責為AMD、蘋果、英偉達和高通等公司生產晶片。

在英特爾和 AMD 的商業模式下,我們遇到了一個很大的問題。他們的商業模式的基礎是銷售通用 CPU,人們只需將其插入大型 PC 主機板即可。因此,計算機制造商只需從其他供應商那裡購買主機板、記憶體、CPU 和顯示卡,並將這些晶片整合到一個解決方案中。

但是,如今的發展趨勢正在迅速遠離這種模式。在新的單片系統世界中,你無需組裝來自不同供應商的物理元件。相反,你需要組裝不同供應商的智慧財產權。首先,你需要從各個供應商那裡購買顯示卡、CPU、調變解調器、IO 控制器和其他產品的設計,並將其用於內部的單片系統設計。然後,再透過某家代工廠來生產。

那麼,問題來了:因為英特爾、AMD 或英偉達都不會向戴爾或惠普發放智慧財產權許可,不會給他們機會製造自己的單片系統。

當然,英特爾和 AMD 可能也會銷售完整的單片系統。但是其中包含什麼呢?每個 PC 製造商對單片系統所包含的內容可能都有各自的看法。英特爾、AMD、微軟和 PC 製造商之間可能會出現衝突,因為這些晶片需要軟體支援。

對於蘋果來說,這並不是什麼難事,因為他們控制著所有環節。例如,他們為開發人員提供了 Core ML 庫,方便他們編寫機器學習程式碼。至於 Core ML 是在蘋果的 CPU 上執行還是在 Neural Engine 上執行,並不是開發人員所關心的實現細節。

加快 CPU 執行的根本難題

因此,異構計算是 M1 晶片實現高效能的部分原因,但不是唯一的原因。M1 晶片上的通用 CPU 核心 Firestorm 確實非常快。這是 Firestorm 與過去的ARM CPU 的一個重大差異,過去的 ARM CPU 核心與 AMD 和英特爾的核心相比非常弱。

然而,Firestorm 擊敗了大多數英特爾核心,而且幾乎戰勝了最快的 AMD Ryzen 核心。按照傳統經驗來看,這種情況並不會發生。

原則上,你可以結合以下兩種策略來加快 CPU 的速度:

快速執行更多指令並行執行大量指令

在上個世紀 80 年代,快速執行更多指令很容易。只要增加時鐘頻率,指令就會加速完成。一個時鐘週期是計算機執行某項操作的時間。但是一個時鐘週期可能不夠用,因此,有時一條指令可能需要多個時鐘週期才能完成,因為它由幾個較小的任務組成。

但是,如今我們幾乎不可能再提高時鐘頻率了。經過人們十多年堅持不懈的努力,如今摩爾定律已經失效了。

因此,我們所能做的只能是並行執行儘可能多的指令。

多核與亂序處理器

並行執行大量指令的方法有兩種。一種是新增更多 CPU 核心。從軟體開發人員的角度來看,這就如同新增執行緒。每個 CPU 核心就是一個硬體執行緒。如果你不知道執行緒是什麼,則可以將其視為執行任務的程序。一個擁有兩個核心的 CPU可以同時執行兩個單獨的任務,即兩個執行緒。而任務可以理解為儲存在記憶體中的兩個單獨的程式,或者是同一個程式執行兩次。每個執行緒都需要一些記錄,例如該執行緒在程式指令序列中的當前位置。每個執行緒可以儲存臨時的結果,而且應該分開儲存。

原則上來說,處理器即便只擁有一個核心也可以執行多個執行緒。在這種情況下,處理器需要暫停一個執行緒,將當前程序儲存下來,然後再切換到另一個執行緒。稍後再切換回去。這種做法無法帶來太多效能上的提升,而且只能在某個執行緒需要頻繁停下來等待使用者輸入,或網路連線速度太慢的情況才能使用。以上這些可以稱為軟體執行緒。硬體執行緒則意味著需要使用額外的物理硬體(例如額外的核心)來加快處理速度。

然而,問題在於,開發人員需要編寫程式碼才能利用這一點。有一些任務(例如伺服器軟體)很容易做到這一點。例如單獨處理每個使用者,這些任務之間彼此獨立,因此擁有大量核心是伺服器(尤其是基於雲的服務)的絕佳選擇。

圖:Ampere Altra Max ARM CPU,擁有 128 個核心,專為雲計算而設計,多硬體執行緒是其優勢之一。

這就是為什麼 Ampere 等 ARM CPU 製造商生產出的 Altra Max 等 CPU 擁有 128 個核心的原因。該晶片是專門為雲計算而設計的。單個核心不需要擁有瘋狂的效能,因為在雲中利用好每一瓦特的功耗,處理儘可能多的併發使用者才是重中之重。

相比之下,蘋果的情況則完全不同。蘋果的產品都是單使用者的裝置。大量執行緒並不是他們的優勢。他們的裝置可用於玩遊戲、編輯影片、開發等。他們希望桌上型電腦擁有精美的、響應速度超快的影象和動畫。

桌面軟體通常不會利用很多核心。例如 8 個核心對電腦遊戲來說就足夠了,128 個核心完全是浪費。相反,這些軟體需要少量更強大的核心。

接下來我們要講的內容很有意思。亂序執行是一種能夠並行執行更多指令、但不需要多執行緒的方式。開發人員無需專門編寫軟體即可享受亂序執行的優勢。從開發人員的角度來看,似乎每個核心的執行速度都加快了。

為了理解其中的工作原理,我們先來了解一些記憶體方面的知識。請求位於某個特定記憶體位置中的資料會很慢。但是,獲取 1 個位元組的延遲與獲取 128 個位元組的延遲並沒有區別。資料是透過資料匯流排傳送的。你可以將資料匯流排視為連線記憶體與 CPU 各個部分的一條通道或管道,資料正是透過這條管道傳輸的。實際上,資料匯流排就是一些可以導電的銅線。如果資料匯流排足夠寬,則可以同時獲取多個位元組。

因此,CPU 一次可以獲取整塊指令,但是這些指令必須逐條執行。現代微處理器採用了亂序執行。

這意味著,這些處理器能夠快速分析指令緩衝區,並檢查哪些指令之間有相互依賴關係。我們舉一個簡單的例子:

01: mul r1, r2, r3    / / r1 ← r2 × r302: add r4, r1, 5     // r4 ← r1 + 503: add r6, r2, 1     // r6 ← r2 + 1

乘法是相對較慢的操作,假設它需要多個時鐘週期才能執行完成。這時,第二條指令就需要等待,因為它需要知道放入 r1 暫存器的結果。

然而,第三條指令(03 行)並不依賴於前面的計算結果。因此,亂序處理器可以開始平行計算這條指令。

但實際情況是,處理器每時每刻都需要處理成百上千的指令,而 CPU 能夠找出這些指令之間的所有依賴關係

它會分析指令,檢查每條指令的輸入,看一看這些輸入是否依賴於其他一個或多個指令的輸出。這裡的輸入和輸出指的是包含先前計算結果的暫存器。

例如,指令 add r4, r1, 5 的輸入 r1 依賴於前一個指令 mul r1, r2, r3 的結果。這些依賴關係連結在一起就可以形成關係圖,而CPU可以使用這個圖進行處理。圖中的節點就是指令,而邊就是連線這些指令的暫存器。

CPU 可以分析這樣的節點圖,並確定它可以並行執行哪些指令,以及在執行哪個指令之前需要等待多個相關的計算結果。

儘管許多指令都可以提前完成,但我們不能將它們作為最終的結果。我們不能提交這些指令的執行結果,因為它們的執行順序不正確。而在使用者看來,這些指令都是按照發行的順序執行的。

就像棧一樣,CPU 將從頂部彈出完成的指令,直到遇到一條未完成的指令。

M1 晶片上的 Firestorm 核心正是藉助了出色的亂序執行功能才變得如此強大。事實上,它比英特爾或 AMD 的任何產品都要強大,甚至可能超過了主流市場上的任何其他產品。

為什麼 AMD 和英特爾的亂序執行不如 M1?

前面在解釋亂序執行的時候,我略過了一些重要的細節,這裡需要再說明一下,否則就很難理解為什麼蘋果能領先,而且英特爾和 AMD 很難超越。

前面說的“棧”的真正名稱叫做“重排序緩衝”(Re-Order Buffer,ROB),它並不包括普通的機器程式碼指令。其中的內容並不是 CPU 從記憶體中獲取並執行的指令,後者屬於 CPU 指令架構(ISA),是那些我們稱為 x86、ARM、PowerPC 等的指令。

但是在內部,CPU 執行的是一系列完全不同的指令集,這些指令對於程式設計師是不可見的。我們稱之為微指令(簡稱 μops)。ROB 中包含的都是微指令。

由於 CPU 盡一切努力並行執行指令,所以 ROB 的這種做法更實際一些。原因是,微指令非常寬(包含更多位元),可能包含各種元資訊。而 ARM 或 x86指令集中無法新增這麼多資訊,因為:

這樣做會導致程式的可執行檔案體積膨脹;會暴露 CPU 的內部工作原理,是否有亂序執行單元,是否有暫存器重新命名等各種細節;許多元資訊僅在當前執行上下文中有意義。

你可以將這個過程理解成寫程式。你有一個公開的 API,需要保持穩定,供所有人使用。這就是 ARM、x86、PowerPC、MIPS等指令集。而微指令是那些用來實現公開 API 的私有 API。

而且,微指令通常更容易被 CPU 處理。為什麼?因為每條指令只做一件非常容易的任務。正常的 ISA 指令可以非常複雜,可能會引發一系列操作,因此需要翻譯成多條微指令。

CISCCPU 通常別無選擇,只能使用微指令,否則複雜的 CISC 指令會讓流水線和亂序執行幾乎無法實現。

而 RISC CPU 還有別的選擇。例如,小型的 ARM CPU 完全不使用微指令。但這也意味著它們沒辦法實現亂序執行之類的操作。

但你可能會問,你說這些有什麼關係嗎?為什麼需要知道這些細節,才能理解為何蘋果超越了 AMD 和英特爾呢?

這是因為,晶片的執行速度取決於填充 ROB 的速度以及使用的微指令數量。填充得越快、越多,並行獲取指令的可能性就越大,因此能夠提高效能。

機器指令由指令解碼器拆分成微指令。如果有多個解碼器,就能並行地拆分更多指令,從而更快地填充 ROB。

這裡就是蘋果和其他廠商出現重大差別的地方。最次的英特爾和和 AMD 的微處理器核心只有四個解碼器,意味著它們可以同時解碼四條指令。

但蘋果有 8 個解碼器。不僅如此,蘋果的 ROB 是英特爾和 AMD 的三倍大小,可以容納三倍的指令。沒有任何主流晶片製造商的 CPU 中有這麼多解碼器。

為什麼英特爾和 AMD 不能新增更多的指令解碼器?

下面,我們來看一看 RISC 的優勢,以及 M1 Firestorm 核心採用的 ARM RISC 架構有哪些出色表現。

你知道,在 x86 中,指令長度約為 1~15 位元組。而在 RISC 上指令是固定長度。這有什麼關係?

如果每條指令的長度都一樣,那麼將一個位元組流分割,並行傳送給 8 個不同的解碼器就非常容易。

但是在 x86 CPU 上,解碼器並不知道下一條指令從什麼地方開始。它必須按順序分析每一條指令才能得知具體的長度。

英特爾和 AMD 採取暴力的方式來解決這個問題,即在每個可能的開始位置嘗試解碼。也就是說,許多錯誤的猜測就只能拋棄。這就導致解碼器變得非常複雜,因此很難新增更多的解碼器。但這對於蘋果不是問題,他們可以很容易地新增更多解碼器。

實際上,新增更多解碼器會帶來更多問題,因此對於 AMD 而言,4 個解碼器就是上限了。

所以,M1 Firestorm 核心能在同一時鐘頻率下產生比 AMD 和英特爾 CPU 多一倍的指令。

有人會說,可以將 CISC 拆分成多條微指令,增加指令的密度,這樣解碼一條x86 指令就可以達到解碼兩條 ARM 指令的效果。

但實際情況並非如此。高度最佳化的x86程式碼很少使用複雜的 CISC 指令,甚至看上去更像 RISC。

但這對英特爾和 AMD 並沒有什麼用,因為即使 15 位元組的指令非常罕見,解碼器也必須處理它們。這種複雜性成為了 AMD 和英特爾新增更多解碼器的阻礙。

但 AMD 的 Zen3 核心更快吧?

據我所知,從效能的角度來看,最新的 AMD CPU 核心 Zen3 比 Firestorm 核心稍稍快一些。但這只是因為 Zen3 核心的時鐘是 5GHz,而 Firestorm 核心的時鐘是 3.2GHz。儘管 Zen3 的時鐘頻率超出了 60%,但效能只不過比Firestorm 快了一點點。

那麼為什麼蘋果不提高時鐘頻率呢?因為更高的時鐘頻率會增加晶片發熱。這是蘋果的主要賣點。與英特爾和 AMD 不同,他們的電腦很少需要散熱。

所以本質上可以說,Firestorm 核心確實優於 Zen3 核心。 Zen3 雖然效能優秀,但代價是高能耗與較大的發熱量。而蘋果並不選擇這條路。

如果蘋果需要更高的效能,那麼他們會新增更多的核心。這樣就能在保持低功率的條件下提高效能。

未來的發展

似乎AMD和英特爾已經陷入了困境:

他們的商業模式很難設計異構計算和單片系統由於舊的x86 CISC指令集的負擔,很難提高亂序執行效能

但這並不意味著窮途末路。他們仍然可以透過提高時鐘頻率、使用更好的散熱、新增更多核心、提高CPU快取等方式。但每一項都有缺點。英特爾的處境最糟糕,因為他們的核心數已經不及 Firestorm,而且他們的單片系統解決方案中的 GPU 也更弱。

新增更多核心的問題在於,對於一般的桌面負載而言,過多核心帶來的收益很低。當然對於伺服器而言,核心數多多益善。

但是,亞馬遜、Ampere 等公司都在研究 128 核心的 CPU。這就意味著英特爾和 AMD 即將面臨雙重夾擊。

但對於 AMD 和英特爾來說,幸運的是,蘋果並沒有在市場上銷售晶片。所以PC 使用者別無選擇。PC 使用者可能會轉而使用蘋果,但畢竟這是一個緩慢的過程。切換日常使用的平臺並不是一蹴而就的事情。

但對於口袋裡有錢、沒有太多平臺依賴的年輕人來說,以後會越來越多地選擇蘋果,從而提高蘋果在高階市場的佔有率,最終會提高蘋果在整個PC市場的佔有率。

M1 之所以如此之快並不是因為技術好,而是因為蘋果堆積了很多硬體。

M1 非常寬(8 個解碼器),還有很多執行單元。它的重排序緩衝有 630 之深,擁有巨大的快取,還有大量的記憶體頻寬。非常強悍的晶片,設計也非常平衡。

另外,這並不是什麼新技術。蘋果的 A 系列晶片每年都在逐步提升。只不過沒人相信手機上用的晶片能超過膝上型電腦的晶片。

31
  • 整治雙十一購物亂象,國家再次出手!該跟這些套路說再見了
  • vivo X60首發!Exynos 1080晶片究竟有多強?