性能與伸縮性
使用線程的一種說(shuō)法是為了提高性能。多線程可以使程序充分利用閑置的資源,提高資源的利用率,同時(shí)能夠并行處理任務(wù),提高系統(tǒng)的響應(yīng)性。 但是很顯然,引入線程的同時(shí)也引入了系統(tǒng)的復(fù)雜性。另外系統(tǒng)的性能并不是總是隨著線程數(shù)的增加而總是提高。
性能與伸縮性
性能的提升通常意味著可以用更少的資源做更多的事情。這里資源是包括我們常說(shuō)的CPU周期、內(nèi)存、網(wǎng)絡(luò)帶寬、磁盤(pán)IO、數(shù)據(jù)庫(kù)、WEB服務(wù)等等。 引入多線程可以充分利用多核的優(yōu)勢(shì),充分利用IO阻塞帶來(lái)的延遲,也可以降低網(wǎng)絡(luò)開(kāi)銷(xiāo)帶來(lái)的影響,從而提高單位時(shí)間內(nèi)的響應(yīng)效率。
為了提高性能,需要有效的利用我們現(xiàn)有的處理資源,同時(shí)也要開(kāi)拓新的可用資源。例如,對(duì)于CPU而言,理想狀況下希望CPU能夠滿(mǎn)負(fù)荷工作。當(dāng)然這里滿(mǎn)負(fù)荷工作是指做有用的事情,而不是無(wú)謂的死循環(huán)或者等待。受限于CPU的計(jì)算能力,如果CPU達(dá)到了極限,那么很顯然我們充分利用了計(jì)算能力。對(duì)于IO而言(內(nèi)存、磁盤(pán)、網(wǎng)絡(luò)等),如果達(dá)到了其對(duì)于的帶寬,這些資源的利用率也就上去了。理想狀況下所有資源的能力都被用完了,那么這個(gè)系統(tǒng)的性能達(dá)到了最大值。
為了衡量系統(tǒng)的性能,有一些指標(biāo)用于定性、定量的分析。例如服務(wù)時(shí)間、等待時(shí)間、吞吐量、效率、可伸縮性、生成量等等。服務(wù)時(shí)間、等待時(shí)間等用于衡量系統(tǒng)的效率,即到底有多快。吞吐量、生成量等用于衡量系統(tǒng)的容量,即能夠處理多少數(shù)據(jù)。除此之外,有效服務(wù)時(shí)間、中斷時(shí)間等用于能力系統(tǒng)的可靠性和穩(wěn)定性等。
可伸縮性的意思是指增加計(jì)算資源,吞吐量和生產(chǎn)量相應(yīng)得到的改進(jìn)。 從算法的角度講,通常用復(fù)雜度來(lái)衡量其對(duì)應(yīng)的性能。例如時(shí)間復(fù)雜度、空間復(fù)雜度等。
Amdahl定律
并行的任務(wù)增加資源顯然能夠提高性能,但是如果是串行的任務(wù),增加資源并不一定能夠得到合理的性能提升。 Amdahl定律描述的在一個(gè)系統(tǒng)中,增加處理器資源對(duì)系統(tǒng)行的提升比率。 假定在一個(gè)系統(tǒng)中,F(xiàn)是必須串行化執(zhí)行的比重,N是處理器資源,那么隨著N的增加最多增加的加速比:
理論上,當(dāng)N趨近于無(wú)窮大時(shí),加速比最大值無(wú)限趨近于1/F。 這意味著如果一個(gè)程序的串行化比重為50%,那么并行化后最大加速比為2倍。
加速比除了可以用于加速的比率外,也可以用于衡量CPU資源的利用率。如果每一個(gè)CPU的資源利用率為100%,那么CPU的資源每次翻倍時(shí),加速比也應(yīng)該翻倍。 事實(shí)上,在擁有10個(gè)處理器的系統(tǒng)中,程序如果有10%是串行化的,那么最多可以加速1/(0.1+(1-0.1)/10)=5.3倍,換句話說(shuō)CPU的利用率只用5.3/10=53%。而如果處理器增加到100倍,那么加速比為9.2倍,也就是說(shuō)CPU的利用率只有個(gè)9.3%。
顯然增加CPU的數(shù)量并不能提高CPU的利用率。下圖描述的是隨著CPU的數(shù)量增加,不同串行化比重的系統(tǒng)的加速比。
很顯然,串行比重越大,增加CPU資源的效果越不明顯。
性能提升
性能的提升可以從以下幾個(gè)方面入手。
系統(tǒng)平臺(tái)的資源利用率
一個(gè)程序?qū)ο到y(tǒng)平臺(tái)的資源利用率是指某一個(gè)設(shè)備繁忙且服務(wù)于此程序的時(shí)間占所有時(shí)間的比率。從物理學(xué)的角度講類(lèi)似于有用功的比率。簡(jiǎn)單的說(shuō)就是:資源利用率=有效繁忙時(shí)間/總耗費(fèi)時(shí)間。
也就說(shuō)盡可能的讓設(shè)備做有用的功,同時(shí)榨取其最大值。無(wú)用的循環(huán)可能會(huì)導(dǎo)致CPU 100%的使用率,但不一定是有效的工作。有效性通常難以衡量,通常只能以主觀來(lái)評(píng)估,或者通過(guò)被優(yōu)化的程序的行為來(lái)判斷是否提高了有效性。
延遲
延遲描述的是完成任務(wù)所耗費(fèi)的時(shí)間。延遲有時(shí)候也成為響應(yīng)時(shí)間。如果有多個(gè)并行的操作,那么延遲取決于耗費(fèi)時(shí)間最大的任務(wù)。
多處理
多處理是指在單一系統(tǒng)上同時(shí)執(zhí)行多個(gè)進(jìn)程或者多個(gè)程序的能力。多處理能力的好處是可以提高吞吐量。多處理可以有效利用多核CPU的資源。
多線程
多線程描述的是同一個(gè)地址空間內(nèi)同時(shí)執(zhí)行多個(gè)線程的過(guò)程。這些線程都有不同的執(zhí)行路徑和不同的棧結(jié)構(gòu)。我們說(shuō)的并發(fā)性更多的是指針對(duì)線程。
并發(fā)性
同時(shí)執(zhí)行多個(gè)程序或者任務(wù)稱(chēng)之為并發(fā)。單程序內(nèi)的多任務(wù)處理或者多程序間的多任務(wù)處理都認(rèn)為是并發(fā)。
吞吐量
吞吐量衡量系統(tǒng)在單位之間內(nèi)可以完成的工作總量。對(duì)于硬件系統(tǒng)而言,吞吐量是物理介質(zhì)的上限。在沒(méi)有達(dá)到物理介質(zhì)之前,提高系統(tǒng)的吞吐量也可以大幅度改進(jìn)性能。同時(shí)吞吐量也是衡量性能的一個(gè)指標(biāo)。
瓶頸
程序運(yùn)行過(guò)程中性能最差的地方。通常而言,串行的IO、磁盤(pán)IO、內(nèi)存單元分配、網(wǎng)絡(luò)IO等都可能造成瓶頸。某些使用太頻繁的算法也有可能成為瓶頸。
可擴(kuò)展性
這里的可擴(kuò)展性主要是指程序或系統(tǒng)通過(guò)增加可使用的資源而增加性能的能力。
線程開(kāi)銷(xiāo)
假設(shè)引入的多線程都用于計(jì)算,那么性能一定會(huì)有很大的提升么? 其實(shí)引入多線程以后也會(huì)引入更多的開(kāi)銷(xiāo)。
切換上下文
如果可運(yùn)行的線程數(shù)大于CPU的內(nèi)核數(shù),那么OS會(huì)根據(jù)一定的調(diào)度算法,強(qiáng)行切換正在運(yùn)行的線程,從而使其它線程能夠使用CPU周期。
切換線程會(huì)導(dǎo)致上下文切換。線程的調(diào)度會(huì)導(dǎo)致CPU需要在操作系統(tǒng)和進(jìn)程間花費(fèi)更多的時(shí)間片段,這樣真正執(zhí)行應(yīng)用程序的時(shí)間就減少了。另外上下文切換也會(huì)導(dǎo)致緩存的頻繁進(jìn)出,對(duì)于一個(gè)剛被切換的線程來(lái)說(shuō),可能由于高速緩沖中沒(méi)有數(shù)據(jù)而變得更慢,從而導(dǎo)致更多的IO開(kāi)銷(xiāo)。
內(nèi)存同步
不同線程間要進(jìn)行數(shù)據(jù)同步,synchronized以及volatile提供的可見(jiàn)性都會(huì)導(dǎo)致緩存失效。線程棧之間的數(shù)據(jù)要和主存進(jìn)行同步,這些同步有一些小小的開(kāi)銷(xiāo)。如果線程間同時(shí)要進(jìn)行數(shù)據(jù)同步,那么這些同步的線程可能都會(huì)受阻。
阻塞
當(dāng)發(fā)生鎖競(jìng)爭(zhēng)時(shí),失敗的線程會(huì)導(dǎo)致阻塞。通常阻塞的線程可能在JVM內(nèi)部進(jìn)行自旋等待,或者被操作系統(tǒng)掛起。自旋等待可能會(huì)導(dǎo)致更多的CPU切片浪費(fèi),而操作系統(tǒng)掛起則會(huì)導(dǎo)致更多的上下文切換。
了解了性能的提升的幾個(gè)方面,也了解性能的開(kāi)銷(xiāo)后,應(yīng)用程序就要根據(jù)實(shí)際的場(chǎng)景進(jìn)行取舍和評(píng)估。沒(méi)有一勞永逸的優(yōu)化方案,不斷的進(jìn)行小范圍改進(jìn)和調(diào)整是提高性能的有效手段。當(dāng)前一些大的架構(gòu)調(diào)整也會(huì)導(dǎo)致較大的性能的提升。
簡(jiǎn)單的原則是在保證邏輯正確的情況小,找到性能瓶頸,小步改進(jìn)和優(yōu)化。
參考資料
©2009-2014 IMXYLZ
|求賢若渴