并发数据结构- 1.1.1 性能
原文鏈接,譯文鏈接,譯者:俞升兵,校對:周可人
1.1.1 性能
一個運(yùn)行在P個處理上的應(yīng)用程序的加速度是它在單個處理器上的執(zhí)行時間和在P個處理器的執(zhí)行時間的比值。這是一種評價應(yīng)用程序?qū)τ跈C(jī)器資源利用程度的衡量。理想情況下,我們想要的結(jié)果是線性加速度:當(dāng)我們使用P個處理器的時候,我們希望可以獲得P的加速度(譯者注:例如一個應(yīng)用程序在單處理器的執(zhí)行時間是10秒,那么在雙處理的執(zhí)行時間理想情況下是5秒)。加速度隨著P一起增加的數(shù)據(jù)結(jié)構(gòu)我們稱之為可擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)。在設(shè)計(jì)可擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)的時候,我們必須注意:為了同步使用簡單的方法會嚴(yán)重破壞擴(kuò)展性。
回到基于鎖的計(jì)數(shù)器,我們會發(fā)現(xiàn)鎖會帶來順序性的瓶頸:在任何時間點(diǎn),最多只有一個fetch-and-inc操作是有用的,例如:遞增變量X。這種順序性的瓶頸會對本來能夠到達(dá)的加速度造成令人驚訝的影響。順序執(zhí)行部分代碼對性能帶來的影響已經(jīng)在基于Amdahl’s law的一個簡單公式中闡明了。假設(shè)b是一個程序中順序性瓶頸所占的百分比。假設(shè)在單處理器中運(yùn)行這個程序需要1個時間單位,那么在P個處理器的環(huán)境中,執(zhí)行順序運(yùn)行部分的代碼需要b個時間單位,同時在最好的情況下,并發(fā)部分的代碼消耗(1-b)/p個時間單位,那么加速度最多等于 1/(b+(1-b)/p) 。這意味中如果程序中只有10%是屬于順序性瓶頸的部分,那么在一個10個處理器的環(huán)境中,程序能達(dá)到的加速度最多只有5.3:我們的應(yīng)用只利用了機(jī)器的一半性能。減少順序性執(zhí)行代碼塊的數(shù)量和長度對性能是至關(guān)重要的。在基于鎖的上下文中,這意味著減少申請鎖的次數(shù),降低鎖的粒度:一種用來表示在持有鎖時,執(zhí)行指令數(shù)目的衡量。
我們的簡單計(jì)數(shù)器實(shí)現(xiàn)碰到的第二個問題是內(nèi)存競爭:這是底層硬件為了多線程并發(fā)嘗試訪問相同的內(nèi)存地址所造成的流量的開銷。只有當(dāng)你理解普通的共享內(nèi)存多處理器架構(gòu)一些方面,你才能意識到內(nèi)存競爭。如果保護(hù)著我們計(jì)數(shù)器的鎖就像很多簡單鎖一樣,是使用單一地址實(shí)現(xiàn)的話,那么為了請求鎖,線程必須重復(fù)嘗試修改這個地址。以緩存一致性多處理器為例,包含著鎖的cache line的獨(dú)占所有權(quán)必須重復(fù)的從一個處理器傳輸?shù)絼e的處理器上,這會導(dǎo)致每次嘗試修改內(nèi)存地址的操作都需要長時間的等待,失敗的嘗試獲取鎖的操作會進(jìn)一步加重相應(yīng)的內(nèi)存流量。在1.1.7中我們會討論針對不同類型的共享內(nèi)存架構(gòu)實(shí)現(xiàn)相應(yīng)的鎖,避免類似這樣的問題.
基于鎖的實(shí)現(xiàn)的計(jì)數(shù)器的第三個問題是:當(dāng)持有鎖的線程被延期了,那么所有嘗試獲取鎖的線程都會被延期。這種現(xiàn)象稱為阻塞,阻塞是多道程序設(shè)計(jì)(multiprogrammed)中特有的問題,每個處理器都有多個線程,操作系統(tǒng)會給擁有鎖的線程優(yōu)先權(quán)。對于很多的數(shù)據(jù)結(jié)構(gòu)來說,這個問題可以通過設(shè)計(jì)非阻塞的算法來解決,在非阻塞算法中一個線程的延期不會導(dǎo)致其他線程的延期。根據(jù)定義而言,這些算法不能使用鎖。
下面我們繼續(xù)討論我們的共享計(jì)數(shù)器的例子,分別討論阻塞和非阻塞技術(shù);我們會引入更多和性能相關(guān)的話題.
文章轉(zhuǎn)自?并發(fā)編程網(wǎng)-ifeve.com
總結(jié)
以上是生活随笔為你收集整理的并发数据结构- 1.1.1 性能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu之Docker安装
- 下一篇: [译] Grid 布局完全指南