Outline


What can I learn?


How do computers work perform multiplication?


在了解 GPU 與 GPU 之間的差異前,我們先來看看計算機是如何計算加減乘除的。

image.png

以 CPU 計算乘法為例,CPU 需要先去得 Memory 的資料才可以進行運算,計算完成後還需要把結果放入 Memory 中。

接著來看看矩陣乘法。

image.png

想想看,如果是電腦會怎麼運作?有很多種可能吧!例如可以重複的做剛剛提到的單一運算式的方法,也可以先將所有資料都先讀取到 CPU,在進行所有運算,最後再將結果儲存回 Memory 中。

想當然爾,盡可以能的減少步驟是一個影響效能的關進因素,但除了減少步驟外,還會有其他可以改進效能的方法嗎?顯然是有的。例如請更多的工人一起參與計算這個這些運算式,也就是平行運算!

假設我們有四個工人,我們可以請他們分別計算其中的一格,如此一來,如果有更多的工人,就可以計算更龐大的矩陣運算!

What’s the difference between CPU and GPU?


既然請越多的工人,也就是越多的 CPU 核心,就可以讓電腦運算的更快,那只要不斷新增核心數量不就可以讓電腦越跑越快嗎?但實際上電腦運算有幾個根本限制,舉例來說,不是所有工作都能同時做,很多程式只有一部分可以平行處理,另一部分必須依序執行

為了解決諸如此類的問題,CPU 的設計並不是完全已平行運算為核心,這也就有了 GPU 的誕生。

The Benefits of Using GPUs

運用平行運算的原理,GPU 透過大量核心來實現,如下圖:

https://docs.nvidia.com/cuda/cuda-programming-guide/01-introduction/introduction.html

https://docs.nvidia.com/cuda/cuda-programming-guide/01-introduction/introduction.html

會發現一個 CPU 的 Control Unit 和 L1 Cache 都是綁定在一個 Core 上,而 GPU 為了應付成千上萬的核心,多個核心會共用一個 Control Unit 和 L1 Cache,這帶來了一些好處與缺點。

Advantages:

Limitations:

Flynn's taxonomy

既然我們知道 GPU 以數以萬計的運算單元實作的,為了放入更多的計算單元,實際上的運作方式不會是每個核心各自做自己的數學運算,讓我們用費林分類法(Flynn's taxonomy)來說明。

費林分類法是電腦平行處理系統結構的一種常用分類方法,根據資訊流分成指令和資料兩種,分成了四大類,其中 PU(Processing Unit)作為計算一個 Instruction、一個 Data。

Instruction / Data Single Instruction Multiple Instruction
Single Data 單指令流單數據流(SISD) 多指令流單數據流(MISD)
Multiple Data 單指令流多數據流(SIMD) 多指令流多數據流(MIMD)

image.png

要讓一個核心「獨立作業」,它不能只有負責計算的 ALU(算術邏輯單元),還需要一整套負責處理指令與協調運作的控制電路。這些電路的功能包括:

如果 GPU 的上萬個核心都各自跑各自的,就代表每一個核心都需要一整套完整的指令處理與控制電路。這會消耗大量的晶片面積,使得晶片上能放置的 ALU 數量大幅減少。

透過 SIMD 的設計,可以讓多個計算單元共用同一套控制邏輯,因此能節省大量控制電路的空間,把更多晶片面積用來放置 ALU。

Reduction Algorithm

歸約(Reduction)是一種常見的計算模式,其核心概念是將一組資料透過某種結合運算逐步合併,最終得到單一結果。常見的運算包括加法、最大值、最小值等。

其中,累加(Summation)是最典型的歸約運算之一,其運算子為加法,目標是將一組數值合併為一個總和。

因此,在沒有平行化的情況下,累加運算會形成一條序列化的計算鏈。假設共有 8 個元素需要累加,則需要進行 7 次加法運算,也就是 7 個時間單位 才能完成,如下圖所示。這正體現了在序列實作中,歸約運算因為資料相依性而無法同時進行多個計算。

image.png

看似每個結果都會依賴前一個的結果,但我們其實可以把這八個數字拆成四個部分,在分別相加,最後會四個答案,在繼續兩兩一組,直到最後算出答案,如下圖:

image.png

這個演算法就是 Reduction Algorithm,將「多個元素的集合」透過可結合結合律(Associativity)的特性,反覆合併,這樣只需要 3 個步驟 ($log_2N$) 就能得到最終結果。

在單位時間內,都是做加法運算,但處理的是不同的資料,這就是經典的 SIMD 應用。

Parallel vs Concurrent

想要達到看似平行處理的效果,有兩種方式,分別是並行(Concurrent) 與平行(Parallel)。

Concurrent 意味著:多個任務在單個核心中頻繁地切換任務,達成看似多個任務同時處理的效果。

Parallel 意味著:多個任務在各不同的核心中執行,實現真正的平行化處理。

https://www.youtube.com/watch?v=RlM9AfWf1WU

https://www.youtube.com/watch?v=RlM9AfWf1WU

當沒有 Concurrent 與 Parallel 意味著需將不同任務以順序的方法執行,透過 Concurrent 會將任務拆分成不同時間段給單個核心執行,Parallel 則是兩個核心執行各執行一個任務,最後我們也可以兩個核心執行四個任務,透過 Concurrent 與 Parallel 的方法。

What are GPUs used for?


GPU 的發展主有有兩大領域,分別是「圖形渲染」與「高效能 GPU 計算」。

image.png

廠商會根據不同的場景設計 GPU,軟體開發商為了能夠兼容不同的 GPU,需要一種通用的 API,讓軟體開使用,常見的包括 OpenCL、OpenGL、Direct 3D、HIP。這些定義如何表達程式的模型,我們稱之為 Programming Model。

Programming Model and Execution Model


image.png

Programming Model

Programming Model 是一種抽象化的思維框架,用來描述「程式應該如何表達計算、資料如何被組織,以及計算單元之間如何互動」,簡單來說,它就像是一種解題的招式,開發者可以透過開發商定義的招式實作想要的功能。

它不等同於程式語言,而是介於演算法與實際硬體/系統之間的一層設計概念,這看起來非常抽象,讓我們實際透過一些例子來理解他吧!

Sequential Model