首頁>科技>

比較偏技術向,記得關注哦

雖然現在超執行緒(Hyper-Threading)被大家廣泛接受,並把所有一個物理核心上有多個虛擬核心的技術都叫做超執行緒,但這其實是Intel的一個營銷名稱。而實際上這一類技術的(學術/技術)通行名稱是同步多執行緒(SMT,Simultaneous Multithreading)技術。SMT技術初衷是透過提升CPU核心後端執行單元的利用率,來提升整體的並行效能。

Intel的SMT技術是我們認知最廣泛的,早在2002年的Pentium 4上(應該是Pentium 4的E)和Xeon上,Intel就把SMT技術包裝成Hyper Threading,並推向市場了。之後因為架構切換,在酷睿誕生初期暫停過一段時間,而自從Core i7 960這個劃時代的酷睿後,就一直是Intel中高階CPU的標配了。 Intel的超執行緒一直都是SMT2,也就是一個物理核心虛擬出兩個核心,也就是邏輯核心。 AMD最新的Zen系列CPU,也同樣加入了SMT2的超執行緒,現在超執行緒技術可以說是PC和伺服器CPU的標配了。

想和大家分享幾個關於超執行緒的常見問題:

1、SMT為什麼能提升並行效能(多執行緒效能)?

SMT技術雖然是提升多執行緒下表現的效能,但SMT實際上是提升CPU單核效能大背景下的“副產品”。 一個單核單執行緒任務,在CPU的視角上,可以被看作是執行一連串連續的指令。比如說是下面這個例子裡,假設執行的就是一個包含10個指令的任務:

任務1 = A1 A2 B1 C1 D1 A3 A4 D2 C2 B2

我們先看最簡單的場景,CPU執行這些任務最直接的辦法就是一個指令一個指令的執行,假設這些指令的執行週期都是N,那麼執行完這些指令,就需要10N個週期。那麼CPU的速度就只和CPU的頻率相關了,顯然這也不符合我們的認知,不同CPU在相同頻率下的效能顯然不一樣。

除了頻率以外,要提升CPU的單核效能,第一個常見手段就是儘可能的縮短每個指令執行的週期,不過在我們假設的這個場景中和SMT關係不大,這裡就不說了。第二個常見手段就是指令集並行(ILP)。雖然說這個任務1理論上是得一個指令接著一個指令的執行,但實際上這些指令並一定只能這麼順序執行,只要兩個指令之間沒有相互依賴和衝突,那麼就可以併發執行(一起執行),從而縮短總的執行時間。 例如在上面這個例子中,我將指令分組成A B C D四組,組內必須順序執行,組間的指令完全沒有依賴(彼此不依賴對方執行後的資料)和衝突(不共享資源,不是一類操作),那麼我們就可以併發執行這些指令。

任務1A:A1 A2 A3 A4任務1B:B1 B2任務1C:C1 C2任務1D:D1 D2

那麼我們還是假設每個任務的執行週期是N,可以看到只要我們按照上述分組執行程式碼,那麼整體的執行時間就只取決於最長的一組任務1A,也就是執行時間可以縮短到4N,速度提升到2.5倍。

顯然,如果說要在一個CPU核心裡同時執行上述幾組任務,那麼CPU自然得具備至少4組執行埠,這裡我們也簡化成PA、PB、PC和PD,分別執行上述的1A 1B 1C 1D。所以現代的CPU要提升單核效能,都會盡可能的把後端的執行埠數目變多,並且儘可能的在單位時間內讀入更多指令,從而促進指令間的併發。

但是,實際的任務裡,指令之間的依賴衝突關係是錯綜複雜的,不可能完美地將指令均勻地分組到每一個埠上。 就比如說我們上面這個例子裡,在併發執行後雖然時間縮短為了4N個週期,但是實際上只有埠PA是一直在工作的,而PB PC PD都會在中途閒下來。

以Skylake為例子,後端執行埠EU不只一個

隨著單核效能的不斷提升,後端執行資源也越來越豐富,這種執行埠閒置的情況就會越來越明顯,造成資源浪費。這時候,為了將這些資源物盡其用,同步多執行緒SMT就應運而生了。SMT的思路是這樣的,既然一個任務填不滿後端的資源,那麼我們就找不只一個任務來填就好了,不同任務之間的相互依賴和衝突情況很低,放到一起來執行正合適去填滿後端資源。

我們接著舉例子,假設現在有一個新的任務2,同樣是10個指令,同樣按照埠分組:

任務2 = B‘1 A’1 B‘2 C’1 C‘2 D'1 D’2 D‘3 C’3 A‘2任務2A = A’1 A’2任務2B = B’1 B’2任務2C = C’1 C’2 C’3任務2D = D'1 D’2 D‘3 

那麼在指令集併發的情況下,這個任務的執行時間就是3N。

那麼如果把任務1和任務2在單核CPU上分別執行,它們的執行時間就是4N+3N=7N。這時,如果我們引入SMT技術,虛擬出兩個核心來,讓他們同樣在一個核心內執行,依然使用ABCD來表示互相不衝突的指令:

PA:A1 A2 A3 A4 A’1 A’2PB:B1 B2 B’1 B’2PC:C1 C2 C’1 C’2 C’3PD:D1 D2 D'1 D’2 D‘3 

那麼這時候整個執行時間就變成了5N,比起之前的7N又提升40%的速度。這就是SMT技術為什麼能提升多工並行效率的原因。透過引入SMT,可以更為有效的利用後端的資源。在我們這個例子中,兩個任務併發後,只有PB埠空閒了1N個週期。另外SMT技術虛擬出來的核心不一定是2,例如在IBM的Power,Oracle的SPARC,上就SMT8了,我們可以透過引入更多的SMT虛擬核心,來進一步壓榨利用率,只不過隨著SMT虛擬的核心增多,提升的比率是在下降的。例如在我們上面這個例子中,其實融合後只有PB空閒了1N個週期,這時候再引入一個SMT核心,提升並不會很大了。

當然實際的指令執行情況遠比我給的例子複雜,每種指令的執行週期不一樣,指令執行中間可能會有IO等待,執行暫停等情況,但是萬變不離其宗,SMT的思想就是用不同的任務儘可能填滿後端資源,懂了這個例子再考慮這些因素也不難。

2、相比物理多核心,SMT有什麼優勢?

SMT2只需要在前端有兩組維護不同任務上下文的單元就可以

增加物理核心,以及加入SMT都是提升多工效能的方式。但為什麼現在核心那麼多了,還依舊會有SMT? 因為相比於增加物理核心,使用SMT來的更加廉價。因為SMT提供的是虛擬核心,所有虛擬核心共享很大一部分的資源,通常加入SMT技術只需要在前端額外增加一部分資源(畢竟兩個任務是兩個上下文)就可以。例如Intel曾經就披露過,奔騰4增加HT技術只需要多花費5%的核心面積,就可以增加15-30%的多執行緒效能,而如果增加物理核心,增加多少效能,就至少要增加多少比例的核心數量,價效比顯然不如SMT。

3、SMT有什麼代價?

天下沒有免費的午餐,SMT技術帶來多執行緒效能進步的同時,勢必也會引入一些負面的影響。大體有如下一些:

多執行緒維護開銷:我們上面的例子中比較理想的展示了SMT的效果,但也沒展現出SMT的一些代價。一個物理核心如果引入多個執行緒,那麼是要協調、隔離多個執行緒的,這會引入額外的開銷。所以最理想的情況下,如果一個核心有兩個執行緒,那麼兩個執行緒的總執行時間會更快,但是如果細分到每一個執行緒的執行時間,會比分別執行來的慢一些。資源衝突:此外,在SMT核心中,因為多個邏輯核心會共享很多資源,如果兩個執行緒的性質比較接近,總是在使用類似的資源,那麼它們會遭遇資源衝突。程度輕一點的情況下,互相等待一下就好,多犧牲一點單執行緒效能,還能保證多執行緒效率。而差一點的情況就是資源衝突反而導致效能下降,最典型的衝突就是快取的衝突,一個執行緒可以用100%的快取,而超過一個執行緒使用同一個快取,可用快取就不是100%,會導致大量開銷極大的快取-記憶體換入換出。只要有一個執行緒是非常吃快取的,那麼加入SMT不但不會提升總的執行效率,反而會降低整體的效率。SMT非常忌諱不同執行緒的資源衝突,一但衝突SMT就很容易引入反面效果。比如在很多雲伺服器、HPC伺服器上,SMT通常是關閉的,就是因為資源衝突。執行緒安全問題:兩個執行緒在同一個核心內執行,是需要嚴格隔離它們的上下文的,執行緒A不能訪問修改其他執行緒的資源。執行緒隔離是一個非常複雜和繁瑣的過程,如果隔離不徹底,那麼會導致執行錯誤、以及隱私洩漏的問題。Intel前兩年Skylake爆發的若干安全漏洞,就是因為執行緒隔離不到位造成的。導致功耗增加:SMT整體的思路是略微犧牲單核效能/能耗比,換取大多數情況下的多執行緒時的單核效能和能耗比,那麼對應的加入SMT後單核的能耗比會有些許倒退。由於引入SMT會導致核心設計更加複雜,靜態功耗、漏電會更難控制,這對於移動裝置是致命的。這也是為什麼SMT在PC和伺服器上大行其道這麼多年,手機上幾乎看不到的原因。4、為什麼有的核心沒有SMT,有的有SMT2,有的有SMT4等?

相信到這裡,大家已經明白,SMT是有利有弊的,SMT不是絕對的好,也不是絕對的壞,只有最合適的SMT配置。如果一個核心的後端資源空閒並不多,或者通常的多工場景任務間衝突比較大,那麼SMT就不應該配置或者應該少配置。比如Intel的Atom線最開始在非亂序核心中是有HT的,後面因為引入了亂序執行後,後端已經被填得很慢了,引入SMT的開銷會大於其收益,自Silvermont後就沒有SMT了。比如說在我們桌面環境下,其實SMT2已經差不多夠用了(架構層面&任務層面),再多的SMT只會反向引入開銷。

因為現在的多核大戰,無論是PC還是手機,多執行緒效能絕大部分時候都是多餘的,除了跑分和極端應用,很少能用到多核效能,要指望它們做更多的虛擬核心,估計近些年是看不到的。

現代的作業系統在排程上都考慮到了SMT的特性,比如你有8個核心16執行緒,那麼在多工要求不是很大的情況下,作業系統會盡量避免讓一個核心同時執行兩個執行緒。那麼那些單核倒退、資源衝突的情況就基本不會發生了。而當多工要求很高的時候,作業系統讓一個核心跑多個執行緒,這時候雖然可能會發生衝突導致效率反向降低,但是更多的時候是增加效率,所以從期望上來說,是沒必要的。

如果追求極致效能且自己確切不需要那麼多多執行緒效能,自然可以關掉。反正也用不到那麼多執行緒,享受不到SMT的好處,還不如索性關了,杜絕一切可能的開銷,也更容易超頻了。所以其實核心越多的,越適合關閉SMT,至於還在用4核心之類的就別關了。

6、如何辨別哪個核心是虛擬核心,哪個核心是物理核心?

很多人經常問,在Windows的任務管理器裡,到底哪個核心是真的,哪個是虛擬的? 這樣可以設定任務相關性,繫結核心。

但其實沒有真假之別,一個核心的兩個邏輯核心情況下,兩個邏輯核心是完全對等的,沒有真假之分。無論你使用A邏輯核心還是B邏輯核心都一樣,無論你繫結哪個邏輯核心,只要不同時用,那麼哪個邏輯核心都約等於是完整佔用的物理核心。

如果對這類偏技術向的文章感興趣,記得關注哦!

20
  • 整治雙十一購物亂象,國家再次出手!該跟這些套路說再見了
  • 人工智慧正在改變建築物的管理方式