http://shiningray.cn/some-facts-about-erlang-and-smp.html
原文:http://groups.google.com/group/erlang-questions/browse_thread/thread/7827f5e32681ca8e
by.Kenneth Erlang/OTP team, Ericsson
譯:ShiningRay
以下是一些Erlang SMP實(shí)現(xiàn)的細(xì)節(jié)和與性能與伸縮性相關(guān)一些簡單介紹。
幾周之內(nèi)還有有一個(gè)關(guān)于多核如何運(yùn)作以及未來如何發(fā)展的更詳細(xì)的介紹。我打算將一些內(nèi)容放在我的報(bào)告中,將于9月27日的ICFP2008,Erlang Workshop在Victoria BC展示給大家。
沒有SMP支持的Erlang VM只有1個(gè)運(yùn)行在主處理線程中的調(diào)度器。該調(diào)度器從運(yùn)行隊(duì)列(run-queue)中取出可以運(yùn)行的Erlang進(jìn)程以及IO任務(wù),而且因?yàn)橹挥幸粋€(gè)線程訪問他們所以無須鎖定任何數(shù)據(jù)。
而帶有SMP支持的Erlang VM可以有一個(gè)或多個(gè)調(diào)度器,每個(gè)運(yùn)行在一個(gè)線程中。調(diào)度器從同一個(gè)公共運(yùn)行隊(duì)列中取出可運(yùn)行的Erlang進(jìn)程和IO任務(wù)。在SMP VM中所有的共享數(shù)據(jù)結(jié)構(gòu)都會(huì)由鎖進(jìn)行保護(hù),運(yùn)行隊(duì)列就是這樣一個(gè)由鎖保護(hù)的數(shù)據(jù)結(jié)構(gòu)。
從OTP R12B開始,如果操作系統(tǒng)報(bào)告有多于1個(gè)的CPU(或者核心)VM的SMP版本會(huì)自動(dòng)啟動(dòng),并且根據(jù)CPU或者核心的數(shù)量啟動(dòng)同樣數(shù)量的調(diào)度器。
你可以從“erl”命令打印出來的第一行看到它選擇了哪些參數(shù)。例如:
Erlang (BEAM) emulator version 5.6.4 [source] [smp:4] [asynch-threads:0] …..
其中“[smp:4]”表示SMP VM運(yùn)行了4個(gè)調(diào)度器。
默認(rèn)值可以用“-smp [enable|disable|auto]”來替換,auto是默認(rèn)的。如果smp被啟用了(-smp enable),要設(shè)置調(diào)度器的數(shù)量可以使用“+S Number”其中Number是調(diào)度器的數(shù)量(1到1024)
注意1:運(yùn)行多于CPU或核心總數(shù)的調(diào)度器不會(huì)有任何提升。
注意2:在某些操作系統(tǒng)中一個(gè)進(jìn)程可使用的CPU或者核心的數(shù)量可以被限制。例如,在Linux中,命令“taskset”就可以實(shí)現(xiàn)這個(gè)功能。 Erlang VM目前還只能探測(cè)CPU或者核心的總數(shù),不會(huì)考慮“taskset”所設(shè)置的掩碼。正因如此,例如可能會(huì)出現(xiàn)(已經(jīng)出現(xiàn)過了)即使Erlang VM運(yùn)行了4個(gè)調(diào)度器,也只使用了2個(gè)核心。OS會(huì)進(jìn)行限制因?yàn)樗紤]“taskset”所設(shè)置的掩碼。
每個(gè)Erlang VM的調(diào)度器都運(yùn)行于一個(gè)OS線程上,是OS來決定線程是否執(zhí)行在不同的核心上。一般來說OS會(huì)很好地處理這個(gè)問題并且會(huì)保證線程在執(zhí)行期間運(yùn)行于同一個(gè)核心上。
Erlang進(jìn)程會(huì)被不同的調(diào)度器運(yùn)行,因?yàn)樗麄兪菑囊粋€(gè)公共運(yùn)行隊(duì)列中被取出,由首先可用的調(diào)度器運(yùn)行。
性能和伸縮性
只有一個(gè)調(diào)度器的SMP VM要比非SMP的VM稍微慢那么一點(diǎn)點(diǎn)。SMP VM內(nèi)部需要用到各種鎖,不過只要不存在鎖的爭用,那么由鎖引起的開銷不會(huì)非常大(就是鎖爭用上面需要花時(shí)間)。這也解釋了為何在某些情況下,運(yùn)行多個(gè)只有一個(gè)調(diào)度器的SMP VM要比包含多個(gè)調(diào)度器的單一SMP VM更加高效。當(dāng)然運(yùn)行多個(gè)VM要求應(yīng)用可以按照多個(gè)并行任務(wù)的方式運(yùn)行并且之間沒有或者幾乎不通訊。
一個(gè)程序是否能在多核上的SMP VM中良好地進(jìn)行提升很大程度上取決于程序的性質(zhì),某些程序可以保持線性提升至8核甚至16核,同時(shí)其他某些程序基本不能提升,連2核都不行。實(shí)際應(yīng)用中很多程序都能在主流市場(chǎng)的核心數(shù)上得到提升,見下文。
若并行的持續(xù)“通話”由每個(gè)核心一個(gè)或多個(gè)Erlang進(jìn)程來表示,實(shí)際的支持大量通話的電信產(chǎn)品已經(jīng)先現(xiàn)出在雙核和四核處理器上不俗的伸縮性。注意,這些產(chǎn)品是在SMP VM和多核處理器出現(xiàn)很久以前按照普通的Erlang風(fēng)格來寫的,他們也能無須任何修改甚至不需重新編譯代碼就能從Erlang SMP VM中獲益。
SMP性能得到持續(xù)改進(jìn)
SMP實(shí)現(xiàn)正被不斷改進(jìn)以便能得到更好的性能和伸縮性。在每個(gè)服務(wù)發(fā)布版R12B-1,2,3,4,5…,R13B等等中,你都能發(fā)現(xiàn)新的優(yōu)化。
一些已知的瓶頸
單一的常見運(yùn)行隊(duì)列隨著CPU或核心的數(shù)量的增加會(huì)成為一個(gè)顯著的瓶頸。
這從4核開始往上就會(huì)顯現(xiàn)出來,不過4核仍然可以為多數(shù)應(yīng)用程序提供不錯(cuò)的性能。我們正在從事一個(gè)每個(gè)調(diào)度器一個(gè)運(yùn)行隊(duì)列的解決方法作為目前最重要的改進(jìn)。
Ets表格會(huì)引入鎖。在R12B-4之前在每次對(duì)一個(gè)ets-table的訪問中會(huì)用到兩個(gè)鎖,但是在R12B-4中meta-table的鎖被優(yōu)化過,可以顯著減少爭用(前面已經(jīng)提到爭用是有很大代價(jià)的)。如果很多Erlang進(jìn)程訪問同一個(gè)表格,就會(huì)有很多鎖爭用造成性能降低尤其當(dāng)這些進(jìn)程主要工作是訪問ets-table。鎖存在于表級(jí)而非記錄級(jí)。注意!這也會(huì)影響到Mnesia因?yàn)镸nesia用到了很多ets-table。
我們關(guān)于SMP的策略
當(dāng)我們開始實(shí)現(xiàn)SMP VM的最初,我們就確定了策略:“首先讓它可以運(yùn)行,然后測(cè)量,然后優(yōu)化”。自從2006年五月我們發(fā)布了第一個(gè)穩(wěn)定的SMP VM(R11B)以來,我們一直遵循著這個(gè)策略。
還有更多已知的東西可以改進(jìn),我們會(huì)按照性能的收益大小先后各個(gè)擊破。
我們將主要的精力放在多核(大于4)上更好的連續(xù)伸縮性上。
卓越典范
即使SMP系統(tǒng)有還有一些已知的瓶頸不過已經(jīng)有不錯(cuò)的整體性能和伸縮性,同時(shí)我相信在讓程序員利用多核機(jī)器事半功倍方面,我們是一個(gè)卓越的典范。