測試10秒鐘,分析數小時,CPU性能只看跑分可不夠

寫在前面

      大約4年前在中科院軟件所,爲評估國產兆芯CPU性能,我接觸到一些benchmark,涉及CPU指標的就有ubench、sysbench、c-ray、SPEC和unixbench等。

       工具在手,不要動腦,跑起來就行。後來情況變了,每個月都有數個系統性能調優的kpi壓在身上,你不光要知道這些性能怎麼測,還得分析瓶頸在哪,最後還要不斷實驗去提升性能。

       能力有限,很多就不會去關注,像sysbench也是個老掉牙的benchmark了,誕生到現在有15年曆史,一個工具走到現在,還有它使用的場景,那肯定有它的價值。

       正巧最近又需要驗證虛擬化下CPU的性能,仍然利用sysbench去測試,這次既然測了,就不單單隻看跑分,看看數據背後的意義。       

       整篇文章分以下幾小章節:

          一  sysbench測試CPU的過程

   二  計算素數對CPU性能的參考價值

   三  如何評估測試數據

          四  總結


一 sysbench測試CPU的過程

       使用benchmark前,不妨先看下readme,sysbench在CPU上是這樣自我定義的:

      'cpu': a simple CPU benchmark

       劃重點:simple。工具設計之初,就不是爲CPU考慮的,它最常使用場景基本在mysql等數據庫評測上。所以自評爲simple benchmark,必然有原因,這個後面詳說。

        迴歸正題,sysbench在大多數Linux下建議yum或apt-get安裝,萬一需要手動編譯,需要注意2點:

l  如果你的sysbench是運行在64位CPU上,請先確保編譯的是64位二進制文件;

l  萬一你的環境是32位CPU,要知道在32位CPU上進行64位操作數的運算,需要使用多條32位的彙編指令來模擬其行爲,隨之帶來的性能開銷勢必影響到結果。


(1)一般測試方法

        事先聲明,我用的是sysbench1.0.17版本,自從1.0.8版本後,一改以往使用計算達到10000內素數所用時間爲測試結果, 增加了events per second爲輸出報告。

        測試方法大同小異,sysbench + 參數 + 測試項 + 命令,如下圖:

           image.png        

        以CPU爲例(測試在4線程下CPU的運算速度):

           image.png

        在本例測試中,只是採用最小化參數:--threads,其他常用參數還包括:

         image.png


        根據實際需要,可選擇多種參數組合,本文只採用線程作爲參數,測試結果如下所示:

image.png

       測試輸出清晰,數據一目瞭然,benchmark輕度用戶重點關注2個數據就好,一是Prime numbers limit,二是events per second。

        以上面爲例,最終結果就是計算10000個素數,4線程平均每秒完成event個數爲549.36,數值越大代表性能越好。

        如果只簡單衡量雲主機CPU性能,以上2個結果足夠了,明白了在什麼樣的基數下測試,並且知道每秒完成的events,可以獲得1個基準數據。


(2)sysbench的實現方式

        工具run了起來,數據也拿到了,但是離馬放南山還早。這時候你還不知道數據準確與否,如果是準確的,是不是你想要的最優結果。

        在評估數據之前,先了解下sysbench是怎麼去測試CPU的,做到知己知彼後,再去看測試結果,說不定會有更多體會,特別是把測試中觀察到的性能問題跟系統原理關聯起來。

        sysbench作爲一個多用途開源benchmark,按照框架設計慣例,其CPU、thread、io、memory和數據庫也遵循着鬆耦合的設計,CPU的源碼有獨立的模塊。


  •   簡約不簡單的cpu module

            採用農村包圍城市,先從CPU測試源碼入手,源碼見/src/tests/cpu/sb_cpu.c

            image.png

           圖1:sb_cpu.c 頭文件聲明

            你不熟悉sysbench的代碼結構也沒關係,僅從sb_cpu.c中簡單幾行頭文件聲明,就可以得到很多信息,拋開前面2個config.h、sb_win.h不談(測試環境在Linux上),真正用到的就2個類庫路徑裏面的頭文件:<math.h>、<inntypes.h>和1個內部實現函數聲明的"sysbench.h"。

  image.png


           重點關注"sysbench.h",但具體實現還要看sysbench.c,暫且不表,繼續看/src/tests/cpu/sb_cpu.c         

           image.png

                                                                                                                          圖2:初始化的CPU測試參數

             圖2中,定義了一個cpu默認參數,如果不特別指定,cpu-max-prime默認以10000作爲上限。這裏工具採用static函數聲明的方式,直接引用/src/sb_options.h中的sb_arg_t結構體,簡單聲明測試設置的name、desc、value和type,在以後的sysbench.c會多次調用,如圖3所示:

image.png

圖3:sb_arg_t結構體

             沿着/src/tests/cpu/sb_cpu.c代碼繼續看,是對CPU測試的函數聲明和靜態變量定義,在cpu_test中通過變量可看到CPU性能測試流程,如下圖4中:

image.png

圖4:cpu_test靜態變量的定義

              圖4中,基於sb_test_t的結構體變量cpu_test,ops下所有變量在sb_test_t中引用了sb_operations_t。cpu_test完全依據sb_test_t結構體中包含的數據項,從名稱設置開始,到初始化操作,再到定義核心event函數執行、報告輸出,最後到結束後的動作。短短10幾行,就把CPU測試場景描述清楚了,剩下要做的只是代碼依次執行罷了。

image.png

圖5:cpu-max-prime取值判斷

               

              圖5中,cpu-max-prime在/src/tests/cpu/sb_cpu.c代碼中有單獨實現,其他類似time、event、threads的實現全都放在sysbench.c中。

              sb_get_value_int()函數在sb_options.c中已完成定義,很多參數都要sb_get_value_int去獲取。

image.png

圖6:CPU測試的主要執行環節

                cpu_execute_event是sysbench在CPU性能評估最主要環節,之前代碼多次提到prime字眼,知道是素數,通過百度也知道它的計算原理,但在cpu_execute_event函數中詳細定義了具體計算方式。在這種模式下,每個請求都由素數計算組成,由cpu-max-primes選項指定的值爲上限,所有的計算使用64位整數執行。

image.png

圖7:CPU報告實現

                 圖7中,cpu_report_cumulative是最後的實現環節,採集、統計及打印是一連串的處理過程,如果要實時打印report,要停止運行計時器。具體代碼實現在sysbench.c中sb_report_cumulative(),這是個複雜的處理流程。


  •   管中窺豹看框架

            sysbench測試CPU的代碼沒那麼複雜,素數原理擺在明面,算法固定,自身實現代碼比較清晰,單看素數計算的部分,任何語言都能實現,自己寫個腳本都能直接用,難點主要在events和cumulative處理上,這也是基準工具的魅力所在。

            前文對CPU模塊有了粗略分析,這裏我用一張圖將整個流程貫穿起來,如下圖所示:

           image.png

    圖8:CPU TEST 關係圖

           

          圖8中,除了能看到代碼之間的調用鏈,有一點值得注意,就是幾個struct:sb_test_t、sb_operations_t,前文提過,基於sb_test_t的結構體變量cpu_test,ops下所有變量在sb_test_t中引用了sb_operations_t。

           阿里雲性能專家西邪在他的《sysbench的框架實現介紹》文章中提到一段話:

                    sysbench是一個總體框架,它用來操作各個測性能的計算,那各個部門只需要做的一件事情是聲明需要的實現。只要理解三個struct就可以了    

             文中所提到的三個struct,就是指sysbench.h中的sb_test_t、sb_operations_t和sb_builtin_cmds_t,見下圖9:

image.png

圖9:sysbench case的主要結構體


             從CPU入手看sysbench的實現,3個struct定框架,實現了從測試場景結構到操作結構,再到命令實現結構。

              寫到這裏,對sysbench的框架在本文只是粗略瞭解,有些地方並未深入,比如thread的設計。


二 計算素數對CPU性能的參考價值

       一直覺得數據必須要產生價值,價值就是對外能夠給用戶帶來實際意義,比如幫助用戶虛擬機選型,對內能夠推動研發不斷優化提升用戶體驗等。

       有一段時間,因工作需要,我驗證了很多操作系統的CPU性能,跑了很多次sysbench,最快只要10秒鐘出結果,立等可取。但是跑分不是比大小的game,測的越多越迷茫,甚至都懷疑基準測試是不是認真的,進而對數據打上問號,這樣得出的數據有沒有參考價值?

       sysbench去評估cpu性能,打個比方就像田徑賽事,對cpu的運算測試,包括素數計算,整數,還是浮點數,好比100米、110米欄等比賽,賽道是測試對象,而裁判就是benchmark,都是看誰跑的快。

(1)爲啥要使用計算素數的方式

       在前文第一章節講sysbench readme時說過,評估CPU性能,sysbench只是一個“a simple CPU benchmark",再結合/src/tests/cpu/sb_cpu.c源碼,可清晰看到它就是通過執行64位整數相加、整除等操作來獲取素數,直到滿足設定最大值,這個過程用來評估CPU運算速度。

       所謂素數就是質數,一個大於1的自然數,除了1和它自身外,不能被其他自然數整除的數。

       爲啥要採用素數相加計算來判斷cpu性能?這個可追溯不到歷史,也許當年工具開發者看了電視節目,節目正好講什麼人機大戰、數學猜想等,諸如此類,who care?

(2)素數運算衡量的是CPU什麼能力?

       在講CPU源碼時,提到/src/tests/cpu/sb_cpu.c中cpu_execute_event函數,如下源碼所示:

image.png

       

        利用計算最大素數來衡量CPU運算速度,在代碼中主要使用到的是整數計算(加法),cpu整數能力就是cpu執行加法指令的能力,cpu一秒能執行多少條加法指令,整數運算是cpu最基本能力。

        通過sysbench得到的CPU事務數,能一定程度上反映CPU整數運算性能,但不完整(只涉及加法),相加是衡量CPU整數能力,但是相除就是浮點運算能力(但涉及不多),實際上日常大多數應用(包括sysbench)都是整數計算爲主的程序(會包含少量浮點指令)。

        總結一下,利用sysbench計算素數獲取CPU運算速度,比較接近實際應用CPU場景(不包括GPU),具有代表性。如果想獨立評估CPU整數或浮點運算能力,建議嘗試別的工具。


三 如何評估測試數據

        到了現在,sysbench測試方法熟悉了,結果也有了,把數據填進excel中呈交上去,來杯咖啡可以悠閒的等待下班開黑打野了。不過還沒開心多久,同事就來問你:


image.png

       你不得不重新打開電腦,運行工具,試圖從數字中找到其中的奧祕,可是很快就發現除了從sysbench獲取一組孤零零數字外,空蕩蕩的腦子裏好像啥也沒有留下。是不是白算了?並沒有,CPU不會白算,每一步都算數,測試結果只是空洞的一串數字,還需要人爲賦予價值。

(1)磨刀不誤砍柴工    

       無論是基準測試,還是性能測試,在執行過程中有一個很容易做到,但很多人都忽略的現象:不會做筆記。不是不會做,是壓根不記錄過程中任何輸出,沒有這些記錄,會給後續跟蹤性能問題帶來麻煩,產生問題原因從手指間溜走,時間浪費不說,還容易帶給你負能量。

       我個人使用OneNote收集過程, 文字+圖片任意組合,方便日後追蹤,如果遭遇環境重裝、時間不允許等客觀因素不至於老鼠拉龜,無從下手了。

(2)給測試定基調

       我的同事老王說每次發佈新版,都要對CPU和內存運算能力重新驗證,好像沒意義。

       狹義上的“意義”是啥?意義=價值,就是投入時間後所得到的回報。說到價值,其實在第2章節中分析素數運算衡量CPU什麼能力時已給出了答案,《學霸的黑科技系統》一書在某個章節中也曾提到“梅森素數”,你說梅森素數有什麼用?好像也舉不出什麼實際應用的例子,通常它都是被用作考驗計算機性能,IntelSkylake芯片也曾由此發現bug。

       不能指望每次基準測試都能發現bug,那這個性能評估還要不要做了?在回答問題之前,先要明白基準測試的目的。

image.png


       總結一下:

n  基準測試一般發生在環境變更、版本迭代、配置或參數改變的前後;

n  當爲軟件或系統創建性能基準後,這個數據可作爲參照,用來判斷任意項變更給系統帶來的影響;

n  瞭解系統優化前後的性能提升/下降指標,獲取系統整體性能趨勢,及早識別系統性能風險


 這麼看來,我們的工作還是有做的必要性,但不妨定3個小目標:

image.png


(3)從sysbench中讀懂數據

        sysbench數據模板是固定的,測試結束會將數據直接嵌套進去再呈現到終端。拿到數據先做2個確認:

       →確認1:Number of threads 和你發起測試參數中一致

       →確認2:Prime默認爲10000,除非你發起測試參數中有特別指定值

        步驟正確,參數沒錯,我們從上到下依次看下sysbench輸出的測試數據。

        測試結果中最重要的就是CPU speed,即:所有線程每秒完成的events數,這個數值越大代表性能越好,如下圖10:

image.png

圖10:cpu speed結果

  每秒完成的events數可以理解成跑分,在手機領域每當手機廠商發行新手機產品,各種發佈會上毫不例外的都會附上跑分。但是單看跑分還不夠,還要重視延時。

image.png

圖11:Latency結果

   上圖11中, sysbench給出了Latency的結果,包括min、avg、max和95%時延,類似jmeter輸出,這個數值越小代表性能越好。在分佈式存儲(如ceph)領域,很多指標都將延時作爲重要參考,但在計算能力上,對CPU運算延時重視度並不夠,由於CPU和內存、硬盤不公平的進化規律,很多場景下CPU可能會消耗在IO等待中。

(4)不同工具齊上陣,尋找蛛絲馬跡

       衆所周知在Linux上,應用是不能直接訪問底層硬件,當進程需要訪問硬件時,必須由用戶態模式切換至內核態(暫不考慮KVM虛擬化,在虛擬世界還要藉助intel硬件虛擬化輔助),再通過系統調用訪問硬件。so,在Linux中有一個放之四海皆準的應用負載模式,如下圖12所示:

image.png

圖12:linux應用負載模式


       這裏把sysbench當成一個普通應用,和其他同樣運行在虛擬機linux系統上的程序沒什麼兩樣,當它run起來後,會發生什麼?

       任何應用進程,哪怕複雜度很低,也是依賴Linux庫來執行操作,sysbench測試CPU中一定需調用os庫函數,通過ltrace可以跟蹤進程調用庫函數的情況,如下圖13所示:

image.png

圖13:ltrace庫函數調用情況

        庫函數調用開銷是一個可能存在性能瓶頸的地方,這就要看進程在需要的庫中花費的時間開銷了,先從調用哪些庫函數入手,看看他們分別做了什麼。

image.png

圖14:sysbench庫函數調用矩陣


l  clock_gettime貫穿整個sysbench過程,在庫函數調用中佔了半數,調用了65563次,開銷時間隨着sysbench 的--time參數改變而改變。有一點值得注意的是,sysbench進程已結束,但clock_gettime仍持續長達10秒+調用;

l  log、floor函數調用一直維持在17%左右,這是評估CPU運算所使用的算法核心函數,從時間開銷來看,此處並未發生明顯瓶頸;

l  futex是對內核的調用,主要就是管理進程掛起時的等待隊列以及鎖的睡眠與喚醒操作(即futex_wait、futex_wake)


    ok,通過ltrace定位到進程具體調用庫函數,並且也知道哪些函數調用次數最多,下一步就是要在代碼中找出clock_gettime在哪裏被調用。我們利用sysbench執行測試,自然要在sysbench源碼中去尋找。下圖15是clock_gettime在代碼中的調用位置,只是簡單列出,不包含調用鏈。

image.png

圖15:sysbench代碼中clock_gettime調用位置


            同樣log、floor在sysbench代碼也有相應調用關係,在本文不再詳述。

            至此,毋庸置疑的是clock_gettime在sysbench調用過於頻繁,這是跟sysbench的架構設計有關係,如果通過修改源碼讓其少調用庫函數的次數,或者嘗試修改庫的源代碼,是不是能夠再提高性能?

            醒醒吧,性能真有那麼簡單就下結論?首先修改庫源代碼並不實際,牽一髮而動全身;其次庫函數調用頻繁並不代表此處遭遇瓶頸,需要和資源開銷綜合觀測。


     1)CPU使用率和平均負載

        CPU使用率人人都會查,這是首先能想到CPU監控指標,下圖16是sysbench執行中CPU實時監控情況,可以看到4線程同時在跑,平均分配到4個vCPU上,都滿負荷運行,過去1分鐘的平均負載達到4.06,並且持續在這負載線上。

        結論1:平均負載最理想的情況是等於CPU 個數,4.06代表系統並未發生過載現象

image.png

圖16:CPU使用率


     2)用戶/內核消耗CPU的時間,有無io等待

         下圖17是實時top監控,us100%,內核無CPU消耗,至始至終CPU沒有出現iowait狀態,內存也無開銷,這是一個CPU基準測試工具該有的表現,只針對CPU檢測,不牽連無辜。

         結論2:CPU佔用時間片正常,無等待I/O

image.png

圖17:us/sy/wa的監控

      3)系統、線程上下文切換

         圖18是vmstat實時監控,看到隨着sysbench的運行,in次數增加明顯,上下文切換短時增加,後趨於減小到正常水準。

         結論3:sysbench運行中,中斷次數明顯增加,但不能確定是軟中斷,還是硬中斷;系統上下文切換無異常

image.png

圖18:系統上下文切換/中斷次數

        圖19是利用pidstat監測到的線程開銷,可看到4個sysbench線程均存在非自願的上下文切換,次數維持在5-20之間,上下文切換必然產生性能開銷,但如果超過1萬或者切換次數出現很大增長,就可能出現性能問題。

        結論4:sysbench在多線程運行下會存在非自願的上下文切換,在單線程下則不會發生。整體上下文切換穩定在個位數,不會對性能結果造成明顯影響。

image.png

圖19:線程上下文切換

      4)軟硬件中斷

         之前vmstat監控到中斷次數明顯增加的情形,但無法判斷中斷類型,用mpstat繼續排查後,發現4個vcpu並沒有明顯的中斷髮生,如下圖20中%irq、%soft所示:

image.png

圖20:mpstat監控CPU中斷         

        先排除掉sysbench運行時性能瓶頸導致的中斷增加,再監控下硬中斷/proc/interrupts信息,找到中斷髮生的地方。圖21中,通過測試前後對比,找到硬中斷產生的位置,都是由LOC產生的Local timer interrupts,LOC是LInxu使用的驅動,用戶無法訪問和配置,這些都屬於時間中斷。

        結論5:Local timer interrupts的發生,與頻繁調用clock_gettime有關

image.png

圖21:interrupts實時信息

(5)學會對比

       從資源視角轉了一圈,依次分析了load average、上下文切換、CPU使用、io等待和軟硬件中斷等,除了clock_gettime現象,其他並沒發現明顯性能瓶頸的位置,掉轉船頭,再回到sysbench調用庫函數問題上。

       ltrace是跟蹤系統函數調用好工具,不過精準力度欠缺了些,下面使用perf看一看sysbench在運行中的熱點函數是哪些。

       在圖22中,perf top實時看到當前系統上所有函數執行情況,不過什麼鬼,在虛擬機中perf居然未能定位本地符號表對應的symbol和地址對應關係,有些符號不能解析爲函數名,只能用地址表示,這誰看的懂。

image.png

圖22:虛擬機上perf追蹤各級函數執行情況

        不能解析函數名,猜測是KVM虛擬化問題,找一個物理機用同樣測試參數試下,可以看到sysbench 100%執行的是哪個函數,如圖23所示:

image.png

圖23:物理機上perf實時追蹤

       cpu_execute_event是sysbench評估最主要實現,在前文代碼解讀中已詳細講到。爲了得到更細粒度分析,還可執行annotate,在C和彙編混合顯示下獲取熱點函數下cpu指令,如圖24所示:

image.png

圖24:annotate獲取更詳細的熱點指令

       100%時間開銷在執行cpu_execute_event操作上,分析運行代碼,其中72.08%的時間佔用%rcx一項指令上,這屬於64位彙編參數傳遞的知識範圍。

       我曾經遇到一個奇怪現象,在64位linux系統上,素數運算速度反而低於32位,通過查找指令延遲表發現64位整數除法指令在某國產CPU上的執行時間遠長於32位執行時間。這就解釋了64位操作數編譯成64位可執行程序爲什麼會發生性能異常。

       後來我在cenots 7.2 64位系統上做過對比實驗,確定相同的處理器下,64位系統素數運算速度是高於32位的,CPU64位指令集可以運行64位數據指令,一次可以提取64位數據,比32位提升一倍。

       在64位系統中,增加了比32位系統多的寄存器。當sysbench調用函數時,傳遞參數會發生改變。一般參數都放在寄存器中傳遞,回過頭看下sysbench在參數傳遞的代碼,可以看到一個函數在調用時,前四個整型值依次傳給寄存器 rbx、rax、rcx和rdx。

       因爲涉及知識盲區,這裏不好評價是否存在問題,底層約定的通用參數傳遞方式,硬件層是無法改變,sysbench代碼倒是可以變動,但效果未知。

       如果從主動尋找性能問題無果,可以試試被動對比。所謂被動,是通過對比方式找到可能存在的問題。


     1)不同物理CPU的性能表現

        手上正好有2套不同CPU物理環境,試下物理cpu主頻、核心進程的不同對性能的影響程度。

         image.png

圖25::不同物理CPU下的性能對比


       從圖25折線圖看到,在Intel Xeon E5-2680 V4上執行sysbench基準測試得到的數據優於Intel Xeon E5-2620 v2。

       如果站在普通用戶的角度看,這個結果差強人意,性能領先幅度也就45%左右,要知道從價格上看Intel Xeon E5-2680 V4可是甩E5-2620 v2幾條街的。

       不過考慮到sysbench只是對CPU的部分指標考量,並不能代表全部,慎重起見,需要綜合CPU的架構、主頻、L3緩存、線程數和總線規格一起分析。

image.png

圖26:E5-2680/E5-2620對比


       上圖26是E5-2680 V4和E5-2620 V2對比,E5-2680單個線程實際使用主頻雖只有1292MHZ,但實際性能勝過頻率更高的E5-2620。

       怎麼回事,難道E5-2680裝上了渦輪增壓?1.2T的發動機爆發出超過2.0L自然吸氣的動力?這裏引出新的問題,對於普通雲計算使用者或企業上雲用戶,開通一個虛擬機,是關心高主頻,還是看多核心?

       小朋友才做選擇,讓我選,我兩個都要,高主頻多核心都是王道。不過現實啪啪啪打臉,你不得不考慮成本,貴的東西自然好,但浪費資源也沒必要。所以你需要先明確在虛擬機上要部署什麼應用、什麼使用場景、處理負載多大、是否計算密集型等,還有種特殊情況,有的應用或業務對CPU指令集有要求,比如有的軟件要求AVX指令集支持,這樣IvyBridge架構的CPU就不能選擇了,必須選擇Broadwell以後的CPU。

       除了主頻,CPU的性能還和CPU的架構、工作頻率、Cache大小、支持指令系統等有重要的影響,單一看CPU主頻不準確。

       現代計算或標準型虛擬機大多數使用場景可能是多核多線程並行處理,需要CPU更快更大的緩存來暫存海量數據,這個時候CPU頻率反而其次。

       總之一句話,CPU性能先看架構,再看主頻,然後對比核心線程,最後再看緩存。

    2)不同線程數的性能對比

       我曾經看過一些利用sysbench測試CPU的錯誤例子,操作者會把測試參數中的--threads不斷加大,甚至遠超過虛擬機CPU總核數。

image.png

圖27:threads超過CPU線程數後的表現

       多核CPU在多線程運用下,CPU的運算能力線性提高,如上圖27所示,但當thread超過cpu核數後,CPU運算速度不會再增加。

       通常在實際使用場景中,如果是單核CPU運行多線程技術,執行多線程運算是沒有效果的,而當雲主機需要執行其他IO操作的任務, 比如讀取文件、網絡通訊等, 多線程技術才能發揮作用,因此多核CPU在多線程運用下,CPU運算能力會明顯提高。就好比你就兩條腿怎麼跑的過四條腿,你又不是美國隊長。

       threads不斷增加,遠超過虛擬機CPU總核數後,性能不會提升,只會增加這個CPU平均負載,如下圖28,load average可以看到,在4核CPU虛擬機中,運行8個線程sysbench,導致sysbench線程互相爭搶CPU使用權,負載達到8以上,造成嚴重負載,影響操作系統運行速度。

image.png

圖28:超線程運行導致平均負載增加

     3)和公開數據對比

        很多時候在調查性能過程中,利用別人的經驗,參考別人的數據不安全是壞事,自己閉門造車也要不得,當然這個過程需要慎重進行。

        基於PM測試的全球CPU天梯榜,該排名是基於數千個PerformanceTest基準測試得出的評分,相對公正,如下圖29所示:

image.png

圖29:CPU天梯榜


        除此之外,推薦1個基準測試網站:openbenchmarking.org,這是1個測試結果數據的公共和私有存儲網站,用於共享結果和有效比較多個測試結果集的有效協作。在這個網站有來自全球各地主動推送上來的測試數據。


     4)虛擬機的cpu性能損耗

       虛擬機cpu性能相比宿主機硬件的損耗程度,也是一個用戶關心的:我們創建的KVM虛擬機能實現“零損耗”麼?

       這是一個比較“龐大”的話題,無論使用哪種flavor(規格)創建虛擬機,它的vCPU在宿主機上物理CPU不同核之間調度。在虛擬機上,執行sysbench,命令請求下去後,先經過vCPU到虛擬機os,再調度到物理機CPU上,vCPU在物理機系統上就是1個線程調用,有調度就會產生開銷,有了開銷必然帶來性能上的影響。

image.png

圖30:物理CPU、雲主機vcpu性能對比

       參考上圖30中的數據,在同等硬件環境、相同工具下,虛擬機cpu素數運算性能與物理節點的CPU性能幾乎“一致”,但這裏的“一致”,是有前提的,需要保證在執行測試過程中不會受到其他虛擬機干擾,因爲通常虛擬機 vCPU 是隨機共享,vCPU 的共享方式會根據節點宿主機上其他主機的負載,將 vCPU 調度到不同核心上,當然也可能在同一核心上。

       不過這樣對比並不公平,過於理想化。因爲一個宿主機資源不可能只提供給1臺虛擬機使用,絕大多數的情況下,單個計算節點上同時有多臺虛擬機存活,他們互相爭搶CPU的使用權,另外,宿主機所在Linux系統還可能會將內存交換、軟中斷等進程調度到虛擬機正在使用的物理核上,這些因素疊加必然會導致虛擬機相對於宿主機CPU性能產生抖動(性能抖動又是另外一個話題了)。


四 總結

       測試10秒鐘,分析數小時,一個sysbench測試CPU的過程,看起來不起眼,但很多地方仍然存在疑惑,還需再挖掘。

       從工具執行原理,到操作系統內核影響,涉及編譯器,再到cpu指令集,還有vcpu或qemu-kvm在宿主機的進程調度帶來的性能開銷。各個環節,每一個單獨拿出來都是長篇大論。

       就目前已知的性能問題發現或瓶頸看,可以嘗試四個方向的性能調優方案:

  (1)CPU獨佔

      這是目前各大雲計算廠商常用的方法,前文也提到同一個宿主機節點的cpu資源被多個虛擬機爭搶,且因爲cpu的抖動,增加cpu切換,導致虛擬機計算能力的不穩定。如果使雲主機機獨佔物理CPU,虛擬機的vCPU能夠固定綁定到宿主機的指定CPU上,在整個運行期間,避免CPU浮動,減少CPU切換開銷,能夠一定程度上提高虛擬機CPU計算性能。

  (2)編譯器優化

      不久前華爲發佈最新產品P30,這款手機因爲各種段子火了,另一個火的就是他家的方舟編譯器,號稱可以實現 Android 性能革命。

      不要小看編譯器,它是應用程序和CPU硬件(指令集)之間的橋樑。GCC是目前廣泛應用的Linux系統的默認編譯器,在很多Linux桌面發行版、服務器版上都能看到它的身影,但是在各硬件平臺上卻並不是性能最優的編譯器。

      這裏有2個方向:

n  取消GCC自動編譯,採用人工編譯,開啓GCC全部優化項

n  直接用intel自家開發的ICC取代GCC, Intel基於x86架構CPU開發出ICC,能夠最大程度發揮x86架構CPU的真實性能

  (3)bios調優,啓用睿頻

       曾經有過啓用睿頻大幅提升存儲io性能的經歷,那時對io請求進程做了頻率上限導致性能被壓制。開啓睿頻,可以讓CPU根據實際運行程序的需求,動態增加運行頻率用來提高處理器的性能。

  (4)sysbench庫函數clock_gettime調用

       sysbench對clock_gettime調用頻繁,這雖然與它本身設計有關係,但如果通過修改源碼讓其調用更少庫函數的次數,也是未來的調優方向。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章