多執行緒與超執行緒
記得當初上學的時候,即使是那些對自己專業比較熱愛的同學依然對計算機組成原理和體系結構這種課程提不起興趣來。因為這兩門課涉及到了硬體,而我們大部分人畢業後的工作都是軟體相關,所以會感覺既枯燥又無用。但現在想想,如果我們畢業後悲催的選擇了本行工作,工作很長時間後依然木有涉及到一點核心以及硬體機制的話,我們大可以找個沒人的地方集體痛哭一場。。。今天我要跟大家分享的是多執行緒和超執行緒的一些知識。
在講多執行緒之前,我先講一下神馬是同步、神馬是非同步。簡單的說,同步就是要兩端按照同一個頻率來進行訊息處理,非同步就是兩端按自己的頻率來進行訊息處理。我們略去底層硬體定義的那種晦澀的解釋方式,用比較通俗的語言來解釋下:
同步:傳送方發出資料後,等接收方發回響應以後才發下一個數據包的通訊方式;
非同步:傳送方發出資料後,不等接收方發回響應,接著傳送下個數據包的通訊方式。
如果還不夠形象的話可以看我下面這個比喻:
同步就好比一個痴情的男子去追心愛的姑娘,這位姑娘被打動了就會接受他的愛;如果這位姑娘不接受,他就會不停的追求,直到姑娘答應了,月老的這次任務才算完成;
非同步就好比一個花心的男子不停的去追很多漂亮的姑娘,不同的姑娘反應不同,有的可能立馬就答應,也有的可能要等到嫁不出去再答應,花心的男子當然會跟先答應他的姑娘交往,不會在那傻傻的等待。
所以,好姑娘一般都喜歡同步的男生,非同步也就意味著異心,很顯然,同步存在等待時間,所以追到好姑娘需要耐心。
下面我們講一下多執行緒。假設現在有一個CPU,執行兩個執行緒,那麼這兩個執行緒其實不是並行執行的,在微觀的CPU內部裡面,還是序列處理的。CPU通過執行緒中斷,讓某一個執行緒掛起來,然後切換到另一個執行緒,執行一會兒,再切換回來,使得巨集觀上看上去好像兩個執行緒同時執行一樣。執行緒切換肯定會帶來一定的效能犧牲,於是我們可以增加CPU,這樣就真正的做到微觀上面的執行緒並行了,然而執行緒數大於物理CPU核數後肯定會帶來執行緒切換帶來的效能影響,那為何要用多執行緒呢?
計算機最重要的部位就是CPU,只有當CPU充分利用的時候,計算機的威力才會被髮揮回來,因此我們的目的就是提高CPU的利用率,不讓其空閒。
假設我們現在執行的任何程式都是純非同步的,也就是說沒有存在任何的等待時間,換一句話說CPU從來不會空閒起來,此時的執行緒數如果大於物理CPU個數的話將會得不償失,因為執行緒切換回帶來一定的效能開銷。
然而不幸的是,現實總是那麼的殘酷,世界到處存在等待的時間,CPU也不例外。想想看買票都需要排隊等待呢,換句專業的術語就是“同步”。那我們想想為啥我們現實生活中會發生等待現象呢?因為資源單一,試想一下,如果我們每個人都有票了,那還排啥隊啊,為啥買票,票不在我們手裡唄;為啥排隊,售票點就那麼幾個,人又那麼多,無規矩不成方圓唄。
計算機裡面同樣也是這樣的情況,就那麼幾個硬體,比如我就一個硬碟,可是四個CPU來訪問,這時候CPU多有啥用,你還是得等待,不等待就跟你買票付了錢,人家突然衝過來把票搶走了,神馬素質啊。這就是互斥鎖存在的意義了,訪問共享資源的時候要鎖住執行緒,不能讓其他人來搶劫。別人就只能等待了。
等待意味著什麼,意味著你只能想辦法浪費時間了,睡覺也好,打遊戲也好,聽音樂也好。如果這個執行緒等待了,就相當於它去睡覺了,那如果此時CPU只有一個執行緒呢?這個執行緒等待的時候, CPU就空閒著了。這就是多執行緒存在的意義了,在大多數存在同步等待情況的程式中,執行緒數如果大於物理CPU個數的時候,是可以充分利用CPU,提高效能的。但無限制的加大執行緒數會帶來執行緒切換的開銷,所以一個服務程式的最優執行緒數需要根據具體情況來具體評估。幸運的是,大部分的服務都是存在同步情況的,於是多執行緒就顯得非常有用處了。
那超執行緒神馬東東呢。我們回顧一下多執行緒概念,電腦在執行命令的時候會鎖定了下個將被執行的指令的記憶體儲存位置,使CPU精確地知道從哪兒得到這些指令。當一個執行緒傳送到CPU,這執行緒的記憶體地址就被鎖定,所以CPU明白從哪裡開始執行執行緒。電腦能夠遞增處理每個指令,一直到處理完一個執行緒為止。線上程執行以後,電腦就會重新讀入下個要執行的指令位置。不同執行緒可以彼此相互中斷,即強迫CPU把電腦上當前處理的結算結果儲存在棧裡。而這樣造成的缺陷就是CPU每次只能處理一個執行緒。而超執行緒技術呢?就是讓一個CPU可以每次執行一條以上來自不同執行緒的技術,這樣可以減少很大部分的多執行緒切換操作。不同於提高CPU的時鐘速度和增加快取容量等物理手段,超執行緒技術可以讓系統誤以為系統內有兩塊物理CPU,作業系統就會同時向那‘兩’塊CPU傳送2個執行緒的任務。在帶有超執行緒技術的CPU上, CPU將會嘗試同時執行兩個執行緒(兩個執行緒使用一個cpu上的不同執行單元),因此解決了CPU執行單元利用率低下的問題。不過,如果執行緒的數目小於物理CPU核數的話,那麼其實有無開啟超執行緒其實並沒有多大的區別。只有當開啟的執行緒數目大於CPU核數的情況下其優勢可能才會體現出來,然而這樣的情況也只是在多執行緒比單執行緒更適合的程式才可以,即大量的同步通訊的程式上其多執行緒的效果才會可能體現出來。這時候開啟超執行緒有可能會帶來收益,而且這些執行緒的功能點重合越少,效果越明顯。而一般的商業網路伺服器都存在網路互動的情況,因此超執行緒可能可以帶來一定的提升,然而還是有可能會帶來零收益、甚至反作用的,所以需要經過嚴格的評估測試後再進行決策。