linux power_评估Linux on POWER的性能
linux power
介紹
在現(xiàn)代機(jī)器上,應(yīng)用程序性能評(píng)估可能是一項(xiàng)復(fù)雜的任務(wù)。 通用工具幾乎無(wú)法處理所有性能變量。 每個(gè)工作負(fù)載所強(qiáng)調(diào)的是不同的計(jì)算機(jī)子系統(tǒng)。 測(cè)量和調(diào)整CPU綁定程序與調(diào)整IO綁定或內(nèi)存綁定程序有很大不同。 在本文中,我們重點(diǎn)介紹編譯語(yǔ)言環(huán)境(C,C ++和其他語(yǔ)言)中與CPU綁定和與內(nèi)存綁定的程序。 我們演示如何:
- 查找程序熱點(diǎn) (程序中執(zhí)行的指令所占比例很高的區(qū)域,功能,方法)
- 使用處理器上可用的硬件性能計(jì)數(shù)器來(lái)測(cè)量程序在POWER7上的行為
- 確定用于Linux上性能評(píng)估的工具。
POWER7的CPI模型
了解應(yīng)用程序性能分析始于CPI指標(biāo)的討論。 每條指令的周期數(shù)(CPI)度量是完成一條指令所需的處理器周期數(shù)。 每條指令被分解為多個(gè)階段:經(jīng)典的RISC管道將具有指令獲取階段,隨后是指令解碼/寄存器獲取,執(zhí)行,可選的內(nèi)存訪問(wèn)以及最后的回寫(xiě)。 CPU可以通過(guò)利用指令級(jí)并行性來(lái)提高其CPI度量(以較低的CPI值衡量):每個(gè)階段將在不同階段處理不同的指令。 優(yōu)化時(shí),請(qǐng)嘗試最小化CPI值以最大化系統(tǒng)利用率。 圖1顯示了流水線??處理器中的最佳指令流。
圖1.流水線處理器的最佳指令流
有時(shí)一個(gè)階段不能完全獨(dú)立于其他階段,或者它發(fā)出具有依賴性的指令,迫使處理器在繼續(xù)執(zhí)行之前滿足該需求。 例如,緊隨算術(shù)指令的存儲(chǔ)器負(fù)載使處理器首先僅將數(shù)據(jù)提取到高速緩存或存儲(chǔ)器中,然后發(fā)出算術(shù)指令。 發(fā)生這種情況時(shí),據(jù)說(shuō)處理器管道會(huì)遇到停頓,從而使管道停頓。 圖2顯示了停滯的管道可能是什么樣子。
圖2.帶有停頓的流水線處理器
在圖1和圖2的示例中,請(qǐng)考慮在完全填充的流水線(每個(gè)周期完成一條指令)的11個(gè)操作周期內(nèi),處理器可以執(zhí)行8條指令。 但是,當(dāng)發(fā)生三個(gè)周期的停頓時(shí),只有五個(gè)指令以相同的周期數(shù)執(zhí)行。 性能損失約為40%。 根據(jù)算法的不同,某些停頓是不可避免的。 但是,仔細(xì)的分析可以提供有關(guān)如何重寫(xiě)或調(diào)整某些代碼段以避免此類(lèi)停頓的提示和建議。 在文章“現(xiàn)代微處理器-90分鐘指南”中找到了關(guān)于現(xiàn)代CPU流水線和指令級(jí)并行性的更完整和更生動(dòng)的解釋(請(qǐng)參閱參考資料 )。
CPI細(xì)分模型(CBM)將功能處理器級(jí)與性能計(jì)數(shù)器相關(guān)聯(lián),以顯示哪個(gè)CPU功能單元正在產(chǎn)生停頓。 CBM取決于CPU架構(gòu)和處理器模型。 電源架構(gòu)和英特爾架構(gòu)具有完全不同的CBM。 盡管POWER5 CBM相似,但與POWER7 CBM不同。 圖3顯示了POWER7 CBM的一部分。 (請(qǐng)參閱此信息的文本版本 。)
圖3.部分POWER 7 CBM
在Power Architecture中,硬件性能計(jì)數(shù)器是一組專(zhuān)用寄存器,當(dāng)處理器中發(fā)生特定事件時(shí),其內(nèi)容將更新。 POWER7處理器具有一個(gè)內(nèi)置的性能監(jiān)視單元(PMU),每個(gè)PMU具有六個(gè)線程級(jí)性能計(jì)數(shù)器監(jiān)視程序(PCM)。 其中四個(gè)是可編程的,這意味著可以同時(shí)監(jiān)視四個(gè)事件,并且可能有500多個(gè)性能事件。 POWER7性能計(jì)數(shù)器由組定義,并且PMU一次只能監(jiān)視同一組的事件。 圖3顯示了用于定義POWER7 CBM的性能計(jì)數(shù)器的子集。 圖3中的計(jì)數(shù)器后面有一個(gè)配置文件,用于指示哪個(gè)CPU功能單元導(dǎo)致處理器停頓,并提供有關(guān)如何調(diào)整算法以消除它們的可能提示。
在圖3中 ,白框是在概要文件中監(jiān)視的特定POWER7 PCM。 根據(jù)它們的值,計(jì)算出灰色框[每個(gè)框都標(biāo)有星號(hào)(*)](這些指標(biāo)沒(méi)有特定的硬件計(jì)數(shù)器)。
注:請(qǐng)?jiān)诩埳?#xff0c;“綜合PMU事件參考POWER7”(見(jiàn)POWER7一個(gè)全面的PMU參考相關(guān)主題 )。
Linux上的工具
如何使用POWER7處理器中的PCM? 盡管您可以在POWER上使用各種分析方法,例如硬件中斷,代碼檢測(cè)(例如gprof),操作系統(tǒng)掛鉤(systemtap); PCM提供了一組廣泛的計(jì)數(shù)器,這些計(jì)數(shù)器可直接與處理器功能一起使用。 PCM探查器使用操作系統(tǒng)中斷以固定的時(shí)間間隔不斷采樣處理器寄存器的值。 盡管樣本分析可能導(dǎo)致比指令跟蹤結(jié)果更不精確的數(shù)字結(jié)果,但是它對(duì)整體系統(tǒng)性能的影響較小,并允許目標(biāo)基準(zhǔn)幾乎以全速運(yùn)行。 結(jié)果數(shù)據(jù)不準(zhǔn)確; 它是誤差容限的近似值。
對(duì)于PCM剖析Linux上的兩個(gè)最常用的工具是OProfile和perf (參見(jiàn)相關(guān)主題 )。 盡管兩者都使用相同的原理,并沿著工作負(fù)載的回溯不斷采樣特殊的硬件寄存器(通過(guò)syscall),但它們的配置和使用方式卻不同。
OProfile工具是適用于Linux系統(tǒng)的系統(tǒng)范圍的探查器,能夠以低開(kāi)銷(xiāo)分析所有正在運(yùn)行的代碼。 它由一個(gè)用于收集示例數(shù)據(jù)的內(nèi)核驅(qū)動(dòng)程序和守護(hù)程序以及一些用于將數(shù)據(jù)轉(zhuǎn)換為信息的后概要分析工具組成。 除非您需要帶注釋的源,否則不需要調(diào)試符號(hào)(gcc的-g選項(xiàng))。 使用最新的Linux 2.6內(nèi)核, OProfile可以提供gprof樣式的調(diào)用圖分析信息。 OProfile的典型開(kāi)銷(xiāo)為1-8%,具體取決于采樣頻率和工作負(fù)載。
在POWER上, OProfile通過(guò)觀察性能硬件計(jì)數(shù)器和性能計(jì)數(shù)器的組來(lái)工作,盡管不同的組不能一起使用。 這意味著要從同一工作負(fù)載獲取不同的性能計(jì)數(shù)器,需要使用不同的OProfile事件配置多次運(yùn)行它。 這也意味著您不能同時(shí)觀看整個(gè)POWER7 CBM。 可用的組在前面提到的“ POWER7 PMY詳細(xì)事件描述”文檔中定義,或者通過(guò)運(yùn)行清單1中的命令來(lái)定義:
清單1. OProfile組清單
# opcontrol -l清單2中的命令演示了一個(gè)簡(jiǎn)單的OProfile配置和調(diào)用:
清單2. OProfile POWER7 CPU周期配置
# opcontrol -l # opcontrol -–no-vmlinux # opcontrol -e PM_CYC_GRP1:500000 -e PM_INST_CMPL_GRP1:500000 -e PM_RUN_CYC_GRP1:500000 -e PM_RUN_INST_CMPL_GRP1:500000 # opcontrol --start運(yùn)行清單3中的工作負(fù)載。
清單3. OProfile運(yùn)行命令序列
# opcontrol --dump # opcontrol –-stop # opcontrol --shutdown要獲取性能計(jì)數(shù)器報(bào)告,請(qǐng)發(fā)出清單4中的命令:
清單4. OProfile報(bào)告生成
# opreport -l > workload_report注:請(qǐng)綜合指南OProfile developerWorks文章“識(shí)別性能瓶頸的OProfile適用于Linux on POWER”(見(jiàn)(雖然沒(méi)有更新的POWER7) 相關(guān)主題 )。
在Linux內(nèi)核2.6.29中引入的perf工具可以分析硬件和軟件級(jí)別的性能事件。 該perf工具具有面向像OProfile的被程序?qū)虻膬?yōu)勢(shì),而不是系統(tǒng)。 它具有一些預(yù)設(shè)的性能計(jì)數(shù)器列表,例如“ cpu-cycles OR cycle”,“ branch-misses”或“ L1-icache-prefetch-misses”,并且能夠復(fù)用PMU組以允許收集多個(gè)性能計(jì)數(shù)器來(lái)自不同組的樣本,但同時(shí)會(huì)降低樣本精度。
一個(gè)缺點(diǎn)是,盡管它允許直接收集硬件性能計(jì)數(shù)器,但perf不能識(shí)別POWER7 CBM表示的計(jì)數(shù)器名稱(chēng)。 它需要使用原始十六進(jìn)制數(shù)字代替。 表1是OProfile事件到十六進(jìn)制數(shù)字的映射,您可以將其與perf使用(使用記錄原始事件選項(xiàng))以將CBM用于POWER7。
表1. POWER7性能事件原始代碼
| PM_RUN_CYC | 200f4 |
| PM_CMPLU_STALL | 4000A |
| PM_CMPLU_STALL_FXU | 20014 |
| PM_CMPLU_STALL_DIV | 40014 |
| PM_CMPLU_STALL_SCALAR | 40012 |
| PM_CMPLU_STALL_SCALAR_LONG | 20018 |
| PM_CMPLU_STALL_VECTOR | 2001年 |
| PM_CMPLU_STALL_VECTOR_LONG | 4004a |
| PM_CMPLU_STALL_LSU | 20012 |
| PM_CMPLU_STALL_REJECT | 40016 |
| PM_CMPLU_STALL_ERAT_MISS | 40018 |
| PM_CMPLU_STALL_DCACHE_MISS | 20016 |
| PM_CMPLU_STALL_STORE | 2004年 |
| PM_CMPLU_STALL_THRD | 1001c |
| PM_CMPLU_STALL_IFU | 4004c |
| PM_CMPLU_STALL_BRU | 4004e |
| PM_GCT_NOSLOT_CYC | 100f8 |
| PM_GCT_NOSLOT_IC_MISS | 2001年 |
| PM_GCT_NOSLOT_BR_MPRED | 4001a |
| PM_GCT_NOSLOT_BR_MPRED_IC_MISS | 4001c |
| PM_GRP_CMPL | 30004 |
| PM_1PLUS_PPC_CMPL | 100f2 |
注意 :在IBM Wiki“在POWER7系統(tǒng)上使用perf”中找到有關(guān)perf的全面指南(盡管POWER7尚未更新)(請(qǐng)參閱參考資料 )。
你可以得到與使用的原料代碼perf對(duì)應(yīng)于中定義的POWER7事件OProfile從libpfm4項(xiàng)目(參見(jiàn)相關(guān)主題 ):它們?cè)谔囟ǖ腜OWER7頭(LIB /事件/ power7_events.h)定義。 示例程序examples / showevtinfo還顯示了事件名稱(chēng)和相應(yīng)的原始十六進(jìn)制代碼。
為了獲得計(jì)數(shù)器信息,分析是一種常見(jiàn)的方法。 通過(guò)概要分析,開(kāi)發(fā)人員可以識(shí)別代碼執(zhí)行和數(shù)據(jù)訪問(wèn)中的熱點(diǎn),找到性能敏感的區(qū)域,了解內(nèi)存訪問(wèn)模式等。 在開(kāi)始介紹之前,有必要制定一項(xiàng)績(jī)效評(píng)估策略。 該程序可能由各種模塊和/或動(dòng)態(tài)共享對(duì)象(DSO)組成,可能會(huì)大量使用內(nèi)核,它可能更多地取決于數(shù)據(jù)模式訪問(wèn)(對(duì)L2或L3高速緩存訪??問(wèn)的壓力很大),或者可能專(zhuān)注于向量操作單位。 下一節(jié)將重點(diǎn)介紹可能的績(jī)效評(píng)估策略。
績(jī)效評(píng)估策略
初步的性能評(píng)估是通過(guò)檢查CPU周期利用率計(jì)數(shù)器來(lái)找到程序熱點(diǎn) 。 要在POWER7上執(zhí)行此操作,請(qǐng)觀看表2中列出的事件:
表2. POWER7 CPU周期利用率計(jì)數(shù)器
| PM_CYC | 處理器周期 |
| PM_INST_CMPL | 完成的PowerPC指令數(shù) |
| PM_RUN_CYC | 由運(yùn)行鎖存器控制的處理器周期。 操作系統(tǒng)使用運(yùn)行鎖存器指示何時(shí)進(jìn)行有用的工作。 運(yùn)行鎖存器通常在OS空閑循環(huán)中清除。 通過(guò)運(yùn)行鎖存器進(jìn)行選通可以濾除空閑環(huán)路。 |
| PM_RUN_INST_CMPL | 完成的運(yùn)行指令數(shù) |
運(yùn)行帶有這些事件的OProfile將顯示處理器花費(fèi)在符號(hào)上的總時(shí)間。 下面是一個(gè)例子輪廓輸出用于從與IBM高級(jí)工具鏈5.0功率(見(jiàn)編譯SPECcpu2006基準(zhǔn)套件的403.gcc部件相關(guān)主題 )。 以下是命令opreport -l的輸出。
清單5. 403.gcc基準(zhǔn)測(cè)試的“ opreport-”輸出(計(jì)數(shù)器PM_CYC_GRP1和PM_INST_CMPL_GRP1)
CPU: ppc64 POWER7, speed 3550 MHz (estimated) Counted PM_CYC_GRP1 events ((Group 1 pm_utilization) Processor Cycles) with a unit mask of 0x00 (No unit mask) count 500000 Counted PM_INST_CMPL_GRP1 events ((Group 1 pm_utilization) Number of PowerPC Instructions that completed.) with a unit mask of 0x00 (No unit mask) count 500000 samples % samples % image name app name symbol name 204528 7.9112 32132 1.3848 gcc_base.none gcc_base.none reg_is_remote_cons\tant_p.isra.3.part.4 125218 4.8434 246710 10.6324 gcc_base.none gcc_base.none bitmap_operation 113190 4.3782 50950 2.1958 libc-2.13.so libc-2.13.so memset 90316 3.4934 22193 0.9564 gcc_base.none gcc_base.none compute_transp 89978 3.4804 11753 0.5065 vmlinux vmlinux .pseries_dedicated_\idle_sleep 88429 3.4204 130166 5.6097 gcc_base.none gcc_base.none bitmap_element_\allocate 67720 2.6194 41479 1.7876 gcc_base.none gcc_base.none ggc_set_mark 56613 2.1898 89418 3.8536 gcc_base.none gcc_base.none canon_rtx 53949 2.0868 6985 0.3010 gcc_base.none gcc_base.none delete_null_\pointer_checks 51587 1.9954 26000 1.1205 gcc_base.none gcc_base.none ggc_mark_rtx_\children_1 48050 1.8586 16086 0.6933 gcc_base.none gcc_base.none single_set_2 47115 1.8224 33772 1.4555 gcc_base.none gcc_base.none note_stores清單6. 403.gcc基準(zhǔn)測(cè)試的“ opreport-”輸出(計(jì)數(shù)器PM_RUN_CYC_GRP1和PM_RUN_INST_CMPL_GRP1)
Counted PM_RUN_CYC_GRP1 events ((Group 1 pm_utilization) Processor Cycles gated by the run latch. Operating systems use the run latch to indicate when they are doing useful work. The run latch is typically cleared in the OS idle loop. Gating by the run latch filters out the idle loop.) with a unit mask of 0x00 (No unit mask) count 500000 Counted PM_RUN_INST_CMPL_GRP1 events ((Group 1 pm_utilization) Number of run instructions completed.) with a unit mask of 0x00 (No unit mask) count 500000 samples % samples % samples % app name symbol name 204538 8.3658 32078 1.3965 gcc_base.none gcc_base.none reg_is_remote_consta\nt_p.isra.3.part.4 124596 5.0961 252227 10.9809 gcc_base.none gcc_base.none bitmap_operation 112326 4.5943 50890 2.2155 libc-2.13.so libc-2.13.so memset 90312 3.6939 21882 0.9527 gcc_base.none gcc_base.none compute_transp 0 0 0 0 vmlinux vmlinux .pseries_dedicated\_idle_sleep 88894 3.6359 124831 5.4346 gcc_base.none gcc_base.none bitmap_element_all\ocate 67995 2.7811 41331 1.7994 gcc_base.none gcc_base.none ggc_set_mark 56460 2.3093 89484 3.8958 gcc_base.none gcc_base.none canon_rtx 54076 2.2118 6965 0.3032 gcc_base.none gcc_base.none delete_null_pointer\_checks 51228 2.0953 26057 1.1344 gcc_base.none gcc_base.none ggc_mark_rtx_childr\en_1 48057 1.9656 16005 0.6968 gcc_base.none gcc_base.none single_set_2 47160 1.9289 33766 1.4700 gcc_base.none gcc_base.none note_stores每個(gè)監(jiān)視的事件在輸出中由一對(duì)列表示。 第一列顯示了從PCM中為指定事件收集的樣本數(shù),第二列顯示了其在總樣本數(shù)中所占的百分比。 從該報(bào)告中可以看出,符號(hào)reg_is_remote_constant_p是消耗大多數(shù)處理器周期的符號(hào),并且是代碼優(yōu)化的理想選擇。 此配置文件僅標(biāo)識(shí)哪些符號(hào)消耗最多的CPU周期,而不標(biāo)識(shí)是否充分利用了處理器管線。 您可以通過(guò)比較計(jì)數(shù)器結(jié)果來(lái)調(diào)查管道利用率。
考慮計(jì)數(shù)器PM_INST_CMPL_GRP1 (第二對(duì)列); 符號(hào)bitmap_operation顯示的百分比高于reg_is_remote_constant_p符號(hào)。 對(duì)于每個(gè)完成的處理器指令,此性能計(jì)數(shù)器都會(huì)遞增,而PM_CYC_GRP1僅表示已利用的CPU周期數(shù)。 如果不做進(jìn)一步分析,這可能表明符號(hào)reg_is_remote_constant_p比符號(hào)bitmap_operation包含更多的CPU停頓,因?yàn)闉榉?hào)reg_is_remote_constant_p完成的指令數(shù)量明顯更少。 該配置文件提供了一個(gè)初步提示,指出哪個(gè)符號(hào)可用于后續(xù)的優(yōu)化工作。
在開(kāi)始研究并破解代碼之前,明智的做法是了解工作負(fù)載是否受CPU或內(nèi)存限制。 這很重要,因?yàn)槊糠N工作負(fù)載類(lèi)型的優(yōu)化方法都大不相同。 例如,大多數(shù)內(nèi)存訪問(wèn)來(lái)自高速緩存或主內(nèi)存(與NUMA遠(yuǎn)程節(jié)點(diǎn)內(nèi)存訪問(wèn)相反),而性能幾乎完全取決于所使用的算法和數(shù)據(jù)結(jié)構(gòu)。 要研究?jī)?nèi)存訪問(wèn)模式,請(qǐng)查看表3中的以下兩個(gè)性能計(jì)數(shù)器:
表3. POWER7內(nèi)存利用率計(jì)數(shù)器
| PM_MEM0_RQ_DISP | 讀取分配給主內(nèi)存的請(qǐng)求 |
| PM_MEM0_WQ_DISP | 寫(xiě)分配給主內(nèi)存的請(qǐng)求 |
這兩個(gè)計(jì)數(shù)器可以指示存儲(chǔ)器訪問(wèn)模式是否主要來(lái)自存儲(chǔ)器讀取,寫(xiě)入或兩者。 使用與之前相同的基準(zhǔn)(來(lái)自SPECcpu2006的403.gcc ),該配置文件顯示:
清單7. 403.gcc基準(zhǔn)測(cè)試的“ opreport-”輸出(計(jì)數(shù)器PM_MEM0_RQ_DISP和PM_MEM0_WQ_DISP)
CPU: ppc64 POWER7, speed 3550 MHz (estimated) Counted PM_MEM0_RQ_DISP_GRP59 events ((Group 59 pm_nest2) Nest events (MC0/MC1/PB/GX), Pair0 Bit1) with a unit mask of 0x00 (No unit mask) count 1000 Counted PM_MEM0_WQ_DISP_GRP59 events ((Group 59 pm_nest2) Nest events (MC0/MC1/PB/GX), Pair3 Bit1) with a unit mask of 0x00 (No unit mask) count 1000 samples % samples % app name symbol name 225841 25.8000 289 0.4086 gcc_base.none reg_is_remote_constant_p.\isra.3.part.4 90068 10.2893 2183 3.0862 gcc_base.none compute_transp 54038 6.1733 308 0.4354 gcc_base.none single_set_2 32660 3.7311 2006 2.8359 gcc_base.none delete_null_pointer_checks 26352 3.0104 1498 2.1178 gcc_base.none note_stores 21306 2.4340 1950 2.7568 vmlinux .pseries_dedicated_idle_sl\eep 18059 2.0631 9186 12.9865 libc-2.13.so memset 15867 1.8126 659 0.9316 gcc_base.none init_alias_analysis要觀察的另一套有趣的性能計(jì)數(shù)器是L2和L3對(duì)緩存的訪問(wèn)壓力。 下面的示例使用perf來(lái)剖析SPECcpu2006 483.xalancbmk組件(見(jiàn)相關(guān)主題 )正在使用RHEL6.2 Linux系統(tǒng)GCC構(gòu)建的。 該組件大量使用內(nèi)存分配例程,因此會(huì)給內(nèi)存子系統(tǒng)帶來(lái)很大壓力。 為此,請(qǐng)使用OProfile監(jiān)視表4中的以下計(jì)數(shù)器:
表4. POWER7高速緩存/內(nèi)存訪問(wèn)計(jì)數(shù)器
| PM_DATA_FROM_L2 | 由于需求負(fù)載,已從本地L2重新加載了處理器的數(shù)據(jù)緩存 |
| PM_DATA_FROM_L3 | 由于需求負(fù)載,已從本地L3重新加載了處理器的數(shù)據(jù)緩存 |
| PM_DATA_FROM_LMEM | 處理器的數(shù)據(jù)緩存已從與該處理器位于同一模塊上的內(nèi)存中重新加載 |
| PM_DATA_FROM_RMEM | 處理器的數(shù)據(jù)緩存是從與該處理器位于的模塊不同的內(nèi)存中重新加載的 |
概要文件輸出顯示以下內(nèi)容:
清單8. 489.Xalancbmk基準(zhǔn)測(cè)試的“ opreport-”輸出(計(jì)數(shù)器PM_DATA_FROM_L2_GRP91和PM_DATA_FROM_L3_GRP91)
CPU: ppc64 POWER7, speed 3550 MHz (estimated) Counted PM_DATA_FROM_L2_GRP91 events ((Group 91 pm_dsource1) The processor's Data Cache was reloaded from the local L2 due to a demand load.) with a unit mask of 0x00 (No unitmask) count 1000 Counted PM_DATA_FROM_L3_GRP91 events ((Group 91 pm_dsource1) The processor's Data Cachewas reloaded from the local L3 due to a demand load.) with a unit mask of 0x00 (No unitmask) count 1000 samples % samples % image name app name symbol name 767827 25.5750 7581 0.2525 gcc_base.none gcc_base.none bitmap_element_allocate 377138 12.5618 8341 0.2778 gcc_base.none gcc_base.none bitmap_operation 93334 3.1088 3160 0.1052 gcc_base.none gcc_base.none bitmap_bit_p 70278 2.3408 5913 0.1969 libc-2.13.so libc-2.13.so _int_free 56851 1.8936 22874 0.7618 oprofile oprofile /oprofile 47570 1.5845 2881 0.0959 gcc_base.none gcc_base.none rehash_using_reg 41441 1.3803 8532 0.2841 libc-2.13.so libc-2.13.so _int_malloc清單9. 489.Xalancbmk基準(zhǔn)測(cè)試的“ opreport-”輸出(計(jì)數(shù)器PM_DATA_FROM_LMEM_GRP91和PM_DATA_FROM_RMEM_GRP91)
Counted PM_DATA_FROM_LMEM_GRP91 events ((Group 91 pm_dsource1) The processor's Data Cache was reloaded from memory attached to the same module this proccessor is located on.) witha unit mask of 0x00 (No unit mask) count 1000 Counted PM_DATA_FROM_RMEM_GRP91 events ((Group 91 pm_dsource1) The processor's Data Cachewas reloaded from memory attached to a different module than this proccessor is located on.) with a unit mask of 0x00 (No unit mask) count 1000 samples % samples % image name app name symbol name 1605 0.3344 0 0 gcc_base.none gcc_base.none bitmap_element_allocate 1778 0.3704 0 0 gcc_base.none gcc_base.none bitmap_operation 1231 0.2564 0 0 gcc_base.none gcc_base.none bitmap_bit_p 205 0.0427 0 0 libc-2.13.so libc-2.13.so _int_free 583 0.1215 327 100.000 oprofile oprofile /oprofile 0 0 0 0 gcc_base.none gcc_base.none rehash_using_reg 225 0.0469 0 0 libc-2.13.so libc-2.13.so _int_malloc解釋概要文件輸出表明,大多數(shù)高速緩存壓力來(lái)自L2訪問(wèn),幾乎沒(méi)有需求的L3重載,因?yàn)長(zhǎng)2訪問(wèn)的總和相對(duì)計(jì)數(shù)器樣本值( PM_DATA_FROM_L2 )遠(yuǎn)遠(yuǎn)高于L3需求重載( PM_DATA_FROM_L3 )。 您只能通過(guò)更全面的分析(通過(guò)觀察更多的計(jì)數(shù)器)來(lái)獲取更多信息,例如L2訪問(wèn)是否由于高速緩存未命中而導(dǎo)致CPU停頓。 從此示例配置文件可以得出的結(jié)論是,與高速緩存訪??問(wèn)相比,主存儲(chǔ)器訪問(wèn)( PM_DATA_FROM_LMEM事件)非常低,并且沒(méi)有遠(yuǎn)程訪問(wèn)(事件PM_DATA_FROM_RMEM ),表明沒(méi)有遠(yuǎn)程N(yùn)UMA節(jié)點(diǎn)存儲(chǔ)器訪問(wèn)。 熱點(diǎn)和內(nèi)存訪問(wèn)模式的分析可以為優(yōu)化工作提供指導(dǎo); 在這種情況下,需要進(jìn)行進(jìn)一步分析以找出真正導(dǎo)致CPU停頓的原因,因?yàn)楹?jiǎn)單地識(shí)別工作負(fù)載熱點(diǎn)和內(nèi)存訪問(wèn)模式不足以正確地識(shí)別CPU停頓。
為了提出更好的性能優(yōu)化策略,需要使用perf工具而不是OProfile進(jìn)行進(jìn)一步分析,因?yàn)樾枰瑫r(shí)監(jiān)視許多POWER7 CBM計(jì)數(shù)器( 圖3中所示的22個(gè)計(jì)數(shù)器),并提供更好的性能優(yōu)化策略。 其中許多事件屬于不同的組,這意味著使用OProfile需要多次運(yùn)行相同的工作負(fù)載。 該perf工具將復(fù)用硬件計(jì)數(shù)器的觀看時(shí)指定的柜臺(tái)都在不止一個(gè)組。 盡管這會(huì)導(dǎo)致結(jié)果的準(zhǔn)確性降低,但總體結(jié)果往往與預(yù)期的結(jié)果非常相似,其優(yōu)點(diǎn)是花了更少的分析時(shí)間。
以下示例使用perf來(lái)分析相同的SPECcpu2006 483.xalancbmk組件。 要分析此組件,請(qǐng)發(fā)出清單10中的命令:
清單10.用于生成POWER7 CBM的perf命令
$ /usr/bin/perf stat -C 0 -e r100f2,r4001a,r100f8,r4001c,r2001a,r200f4,r2004a,r4004a, r4004e,r4004c,r20016,r40018,r20012,r40016,r40012,r20018,r4000a,r2001c,r1001c,r20014, r40014,r30004 taskset -c 0 ./Xalan_base.none -v t5.xml xalanc.xsl > power7_cbm.dat此命令將使perf監(jiān)視-c指定的CPU上-e參數(shù)定義的原始事件。 任務(wù)集調(diào)用可確保組件僅在0號(hào)CPU上運(yùn)行。工作負(fù)載./Xalan_base.none -v t5.xml xalanc.xsl可以由另一個(gè)應(yīng)用程序替換以進(jìn)行概要分析。 配置文件完成后,perf命令將輸出一個(gè)簡(jiǎn)單表,其中包含每個(gè)原始事件的總計(jì)數(shù)以及經(jīng)過(guò)的秒數(shù):
清單11. 489.Xalancbmk基準(zhǔn)的“性能統(tǒng)計(jì)”輸出
Performance counter stats for 'taskset -c 0 ./Xalan_base.none -v t5.xml xalanc.xsl': 366,860,486,404 r100f2 [18.15%] 8,090,500,758 r4001a [13.65%] 50,655,176,004 r100f8 [ 9.13%] 11,358,043,420 r4001c [ 9.11%] 10,318,533,758 r2001a [13.68%] 1,301,183,175,870 r200f4 [18.22%] 2,150,935,303 r2004a [ 9.10%] 0 r4004a [13.65%] 211,224,577,427 r4004e [ 4.54%] 212,033,138,844 r4004c [ 4.54%] 264,721,636,705 r20016 [ 9.09%] 22,176,093,590 r40018 [ 9.11%] 510,728,741,936 r20012 [ 9.10%] 39,823,575,049 r40016 [ 9.07%] 7,219,335,816 r40012 [ 4.54%] 1,585,358 r20018 [ 9.08%] 882,639,601,431 r4000a [ 9.08%] 1,219,039,175 r2001c [ 9.08%] 3,107,304 r1001c [13.62%] 120,319,547,023 r20014 [ 9.09%] 50,684,413,751 r40014 [13.62%] 366,940,826,307 r30004 [18.16%] 461.057870036 seconds time elapsed為了分析perf靠在POWER7 CBM,提供了一種Python腳本輸出(檢查在power7_cbm.zip 可下載資源 ),其構(gòu)成從所收集的虛擬和硬件計(jì)數(shù)器的計(jì)數(shù)器度量。 要?jiǎng)?chuàng)建報(bào)告,請(qǐng)發(fā)出清單12中的命令:
清單12. POWER7 CBM python腳本調(diào)用
$ power7_cbm.py power7_cbm.dat將輸出類(lèi)似于清單13的輸出:
清單13. 489.Xalancbmk基準(zhǔn)測(cè)試的“ power7_cbm.py”輸出
CPI Breakdown Model (Complete) Metric : Value : Percent PM_CMPLU_STALL_DIV : 49802421337.0 : 0.0 PM_CMPLU_STALL_FXU_OTHER : 67578558649.0 : 5.2 PM_CMPLU_STALL_SCALAR_LONG : 2011413.0 : 0.0 PM_CMPLU_STALL_SCALAR_OTHER : 7195240404.0 : 0.6 PM_CMPLU_STALL_VECTOR_LONG : 0.0 : 0.0 PM_CMPLU_STALL_VECTOR_OTHER : 1209603592.0 : 0.1 PM_CMPLU_STALL_ERAT_MISS : 22193968056.0 : 1.7 PM_CMPLU_STALL_REJECT_OTHER : 18190293594.0 : 1.4 PM_CMPLU_STALL_DCACHE_MISS : 261865838255.0 : 20.3 PM_CMPLU_STALL_STORE : 2001544985.0 : 0.2 PM_CMPLU_STALL_LSU_OTHER : 202313206181.0 : 15.7 PM_CMPLU_STALL_THRD : 2025705.0 : 0.0 PM_CMPLU_STALL_BRU : 208356542821.0 : 16.2 PM_CMPLU_STALL_IFU_OTHER : 2171796336.0 : 0.2 PM_CMPLU_STALL_OTHER : 30895294057.0 : 2.4 PM_GCT_NOSLOT_IC_MISS : 9805421042.0 : 0.8 PM_GCT_NOSLOT_BR_MPRED : 7823508357.0 : 0.6 PM_GCT_NOSLOT_BR_MPRED_IC_MISS : 11059314150.0 : 0.9 PM_GCT_EMPTY_OTHER : 20292049774.0 : 1.6 PM_1PLUS_PPC_CMPL : 365158978504.0 : 28.3 OVERHEAD_EXPANSION : 590057044.0 : 0.0 Total : 96.1該報(bào)告基于誤差范圍內(nèi)的統(tǒng)計(jì)值,因此最終百分比并不完全準(zhǔn)確。 即使具有很高的錯(cuò)誤余量,也有大約20%的CPU停頓是由于數(shù)據(jù)高速緩存未命中( PM_CMPLU_STALL_DCACHE_MISS )。 最終指令完成百分比( PM_1PLUS_PPC_CMPL )約為28%。
未來(lái)的優(yōu)化應(yīng)該嘗試通過(guò)減少CPU停頓和/或GCT(全局完成表)百分比來(lái)最大化此數(shù)目。 根據(jù)此報(bào)告,另一種分析途徑是識(shí)別發(fā)生停頓的代碼。 為此,請(qǐng)使用perf record命令。 它將跟蹤原始計(jì)數(shù)器的性能,并創(chuàng)建一個(gè)帶有進(jìn)程回溯的映射,從而可以識(shí)別哪個(gè)符號(hào)產(chǎn)生了最多的硬件事件。 這類(lèi)似于OProfile工作方式。 在此示例中,要跟蹤PM_CMPLU_STALL_DCACHE_MISS事件,請(qǐng)發(fā)出清單14中的命令:
清單14. PM_CMPLU_STALL_DCACHE_MISS事件的性能記錄
$ /usr/bin/perf record -C 0 -e r20016 taskset -c 0 ./Xalan_base.none -v t5.xml xalanc.xslperf命令將使用結(jié)果創(chuàng)建一個(gè)數(shù)據(jù)文件(通常為“ perf.dat”)。 可以使用perf report命令以交互方式讀取它,如清單15所示 :
清單15. 489.Xalancbmk基準(zhǔn)的“性能報(bào)告”的輸出
Events: 192 raw 0x2001639.58% Xalan_base.none Xalan_base.none [.] xercesc_2_5::ValueStore::contains 11.46% Xalan_base.none Xalan_base.none [.] xalanc_1_8::XStringCachedAllocator9.90% Xalan_base.none Xalan_base.none [.] xalanc_1_8::XStringCachedAllocator7.29% Xalan_base.none Xalan_base.none [.] xercesc_2_5::ValueStore::isDuplica5.21% Xalan_base.none libc-2.13.so [.] _int_malloc 5.21% Xalan_base.none Xalan_base.none [.] __gnu_cxx::__normal_iterator<xa4.17% Xalan_base.none libc-2.13.so [.] __GI___libc_malloc 2.08% Xalan_base.none libc-2.13.so [.] malloc_consolidate.part.4 1.56% Xalan_base.none Xalan_base.none [.] xalanc_1_8::ReusableArenaBlock<xa1.56% Xalan_base.none Xalan_base.none [.] xalanc_1_8::ReusableArenaBlock<xa1.04% Xalan_base.none libc-2.13.so [.] __free [...]通過(guò)使用POWER7 CBM計(jì)數(shù)器和性能報(bào)告工具進(jìn)行的分析,您的優(yōu)化工作可能會(huì)集中在優(yōu)化符號(hào)xercesc_2_5 :: ValueStore :: contains(xercesc_2_5 :: FieldValueMap const *)上的內(nèi)存和緩存訪問(wèn)上。
此示例只是可能分析的一部分。 POWER7 CBM向您顯示,盡管顯示數(shù)據(jù)高速緩存停頓是造成CPU停頓的主要原因,但裝入和存儲(chǔ)單元( PM_CMPLU_STALL_LSU )和分支單元( PM_CMPLU_STALL_BRU )都是停頓的來(lái)源。 進(jìn)一步的分析可以解決這些問(wèn)題。
案例分析
以下案例研究應(yīng)用了這些性能評(píng)估策略來(lái)分析三角數(shù)學(xué)函數(shù)的實(shí)現(xiàn)。 根據(jù)分析結(jié)果,將確定優(yōu)化機(jī)會(huì)。 本案例研究中使用的函數(shù)是ISO C hypot函數(shù),定義為直角三角形的斜邊的長(zhǎng)度。 該功能由C99 POSIX.1-2001定義為:
double hypot(double x, double y); hypot()函數(shù)返回sqrt(x * x + y * y)。 成功時(shí),此函數(shù)返回邊長(zhǎng)為x和y的直角三角形的長(zhǎng)度。 如果x或y是無(wú)窮大,則返回正無(wú)窮大。 如果x或y是NaN,而另一個(gè)參數(shù)不是無(wú)窮大,則返回NaN。 如果結(jié)果溢出,則會(huì)發(fā)生范圍錯(cuò)誤,并且這些函數(shù)分別返回HUGE_VAL,HUGE_VALF或HUGE_VALL。 如果兩個(gè)參數(shù)都屬于非正規(guī)變量,并且結(jié)果均為非正規(guī)變量,則將發(fā)生范圍錯(cuò)誤,并返回正確的結(jié)果。盡管該算法看起來(lái)很簡(jiǎn)單,但是Infinity和NaN的浮點(diǎn)(FP)參數(shù)處理以及與FP操作相關(guān)的上溢/下溢給性能帶來(lái)了一些挑戰(zhàn)。 GNU C庫(kù)(參見(jiàn)相關(guān)主題 )提供了位于源樹(shù)在sysdeps / IEEE754 / DBL-64 / e_hypot.c hypot將的實(shí)現(xiàn):
注意 :此代碼示例的許可證信息包含在附錄中 。
清單16.默認(rèn)的GLIBC hypot源代碼
double __ieee754_hypot(double x, double y) { double a,b,t1,t2,y1,y2,w; int32_t j,k,ha,hb; GET_HIGH_WORD(ha,x); ha &= 0x7fffffff; GET_HIGH_WORD(hb,y); hb &= 0x7fffffff; if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} SET_HIGH_WORD(a,ha); /* a <- |a| */ SET_HIGH_WORD(b,hb); /* b <- |b| */ if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */ k=0; if(ha > 0x5f300000) { /* a>2**500 */ if(ha >= 0x7ff00000) { /* Inf or NaN */ u_int32_t low; w = a+b; /* for sNaN */ GET_LOW_WORD(low,a); if(((ha&0xfffff)|low)==0) w = a; GET_LOW_WORD(low,b); if(((hb^0x7ff00000)|low)==0) w = b; return w; } /* scale a and b by 2**-600 */ ha -= 0x25800000; hb -= 0x25800000; k += 600; SET_HIGH_WORD(a,ha); SET_HIGH_WORD(b,hb); } if(hb < 0x20b00000) { /* b < 2**-500 */ if(hb <= 0x000fffff) { /* subnormal b or 0 */ u_int32_t low; GET_LOW_WORD(low,b); if((hb|low)==0) return a; t1=0; SET_HIGH_WORD(t1,0x7fd00000); /* t1=2^1022 */ b *= t1; a *= t1; k -= 1022; } else { /* scale a and b by 2^600 */ ha += 0x25800000; /* a *= 2^600 */ hb += 0x25800000; /* b *= 2^600 */ k -= 600; SET_HIGH_WORD(a,ha); SET_HIGH_WORD(b,hb); } } /* medium size a and b */ w = a-b; if (w>b) { t1 = 0; SET_HIGH_WORD(t1,ha); t2 = a-t1; w = __ieee754_sqrt(t1*t1-(b*(-b)-t2*(a+t1))); } else { a = a+a; y1 = 0; SET_HIGH_WORD(y1,hb); y2 = b - y1; t1 = 0; SET_HIGH_WORD(t1,ha+0x00100000); t2 = a - t1; w = __ieee754_sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { u_int32_t high; t1 = 1.0; GET_HIGH_WORD(high,t1); SET_HIGH_WORD(t1,high+(k<<20)); return t1*w; } else return w; }此實(shí)現(xiàn)非常復(fù)雜,主要是因?yàn)樵撍惴▓?zhí)行了許多逐位FP到INT的轉(zhuǎn)換。 假定使用浮點(diǎn)指令比使用定點(diǎn)指令時(shí)某些FP操作(例如比較和乘法)的開(kāi)銷(xiāo)更大。 在某些架構(gòu)上確實(shí)如此,但在Power Architecture上卻不是。
評(píng)估此實(shí)現(xiàn)的第一步是創(chuàng)建一個(gè)可配置的基準(zhǔn)。 在這種情況下,由于它只是一個(gè)帶有兩個(gè)參數(shù)的函數(shù)和一個(gè)簡(jiǎn)單的算法(沒(méi)有內(nèi)部函數(shù)調(diào)用或其他路徑),因此可以創(chuàng)建一個(gè)簡(jiǎn)單的基準(zhǔn)來(lái)對(duì)其進(jìn)行評(píng)估(請(qǐng)參閱可下載資源中的hypot_bench.tar.gz)。 基準(zhǔn)是績(jī)效評(píng)估的一部分; 優(yōu)化應(yīng)加快利用總工作負(fù)載性能的算法或算法的關(guān)鍵部分。 像這樣的綜合基準(zhǔn)應(yīng)該代表該功能的正常使用。 由于優(yōu)化工作往往是資源和時(shí)間的浪費(fèi),因此需要將精力集中在最常見(jiàn)的使用情況或預(yù)期的行為上。 嘗試優(yōu)化表示總程序使用率較低的代碼往往會(huì)浪費(fèi)資源。
由于這是對(duì)單個(gè)功能的性能分析,因此您可以跳過(guò)熱點(diǎn)分析,而專(zhuān)注于CBM分析。 使用hypot_bench.c中的基準(zhǔn)以及perf , 清單17中的CBM信息:
清單17.“ hypot”基準(zhǔn)測(cè)試的“ power7_cbm.py”輸出
CPI Breakdown Model (Complete) Metric : Value : Percent PM_CMPLU_STALL_DIV : 8921688.0 : 8.7 PM_CMPLU_STALL_FXU_OTHER : 13953382275.0 : 5.0 PM_CMPLU_STALL_SCALAR_LONG : 24380128688.0 : 8.7 PM_CMPLU_STALL_SCALAR_OTHER : 33862492798.0 : 12.0 PM_CMPLU_STALL_VECTOR_LONG : 0.0 : 0.0 PM_CMPLU_STALL_VECTOR_OTHER : 275057010.0 : 0.1 PM_CMPLU_STALL_ERAT_MISS : 173439.0 : 0.0 PM_CMPLU_STALL_REJECT_OTHER : 902838.0 : 0.0 PM_CMPLU_STALL_DCACHE_MISS : 15200163.0 : 0.0 PM_CMPLU_STALL_STORE : 1837414.0 : 0.0 PM_CMPLU_STALL_LSU_OTHER : 94866270200.0 : 33.7 PM_CMPLU_STALL_THRD : 569036.0 : 0.0 PM_CMPLU_STALL_BRU : 10470012464.0 : 3.7 PM_CMPLU_STALL_IFU_OTHER : -73357562.0 : 0.0 PM_CMPLU_STALL_OTHER : 7140295432.0 : 2.5 PM_GCT_NOSLOT_IC_MISS : 3586554.0 : 0.0 PM_GCT_NOSLOT_BR_MPRED : 1008950510.0 : 0.4 PM_GCT_NOSLOT_BR_MPRED_IC_MISS : 795943.0 : 0.0 PM_GCT_EMPTY_OTHER : 42488384303.0 : 15.1 PM_1PLUS_PPC_CMPL : 53138626513.0 : 18.9 OVERHEAD_EXPANSION : 30852715.0 : 0.0 Total : 108.7概要分析表明,大多數(shù)CPU停止運(yùn)行,因此性能損失來(lái)自加載和存儲(chǔ)單元( LSU-計(jì)數(shù)器PM_CMPLU_STALL_LSU_OTHER )。 LSU具有與之關(guān)聯(lián)的各種計(jì)數(shù)器,但是在CPU停頓分析期間,您的重點(diǎn)是與性能下降相關(guān)的計(jì)數(shù)器。 那些顯示POWER上的性能下降的原因與“加載-命中存儲(chǔ)(LHS)”危害相關(guān)。 當(dāng)CPU將數(shù)據(jù)寫(xiě)入一個(gè)地址,然后嘗試過(guò)快地再次加載該數(shù)據(jù)時(shí),會(huì)發(fā)生很大的停頓。 下一步是通過(guò)首先檢查事件PM_LSU_REJECT_LHS (原始代碼“ rc8ac”)來(lái)檢查此特定算法是否發(fā)生這種情況,如清單18所示。
清單18. PM_LSU_REJECT_LHS POWER7事件的性能記錄
$ perf record -C 0 -e rc8ac taskset -c 0 ./hypot_bench_glibc $ perf report Events: 14K raw 0xc8ac79.19% hypot_bench_gli libm-2.12.so [.] __ieee754_hypot10.38% hypot_bench_gli libm-2.12.so [.] __hypot6.34% hypot_bench_gli libm-2.12.so [.] __GI___finite概要文件輸出顯示符號(hào)__ieee754_hypot是生成大多數(shù)PM_LSU_REJECT_LHS事件的符號(hào)。 研究由編譯器生成的匯編代碼,以識(shí)別哪些指令正在生成事件。 通過(guò)在性能perf report屏幕上進(jìn)行迭代并選擇__ieee754_hypot符號(hào),展開(kāi)符號(hào)__ieee754_hypot來(lái)對(duì)程序集進(jìn)行注釋,這將顯示清單19的輸出。
清單19. PM_LSU_REJECT_LHS POWER7事件的性能報(bào)告
: 00000080fc38b730 <.__ieee754_hypot>:0.00 : 80fc38b730: 7c 08 02 a6 mflr r00.00 : 80fc38b734: fb c1 ff f0 std r30,-16(r1)0.00 : 80fc38b738: fb e1 ff f8 std r31,-8(r1)13.62 : 80fc38b73c: f8 01 00 10 std r0,16(r1)0.00 : 80fc38b740: f8 21 ff 71 stdu r1,-144(r1)10.82 : 80fc38b744: d8 21 00 70 stfd f1,112(r1)0.23 : 80fc38b748: e9 21 00 70 ld r9,112(r1)17.54 : 80fc38b74c: d8 41 00 70 stfd f2,112(r1)0.00 : 80fc38b750: 79 29 00 62 rldicl r9,r9,32,330.00 : 80fc38b754: e9 61 00 70 ld r11,112(r1)0.00 : 80fc38b758: e8 01 00 70 ld r0,112(r1)8.46 : 80fc38b75c: d8 21 00 70 stfd f1,112(r1) [...]在代碼的早期,實(shí)現(xiàn)使用宏GET_HIGH_WORD將浮點(diǎn)數(shù)轉(zhuǎn)換為整數(shù) ,以進(jìn)行后繼按位運(yùn)算。 GLIBC的math / math_private.h使用清單20中的代碼定義了宏。
清單20. GET_HIGH_WORD宏定義
#define GET_HIGH_WORD(i,d) \ do { \ieee_double_shape_type gh_u; \gh_u.value = (d); \(i) = gh_u.parts.msw; \ } while (0)導(dǎo)致LHS停頓的可能原因是該操作讀取float的內(nèi)部值屬性,然后將其讀取到變量i 。 POWER7處理器沒(méi)有本機(jī)指令將浮點(diǎn)寄存器的內(nèi)容逐位移動(dòng)到定點(diǎn)寄存器。 在POWER上完成此操作的方法是使用存儲(chǔ)操作將FP編號(hào)存儲(chǔ)在浮點(diǎn)寄存器中的存儲(chǔ)器中,然后將相同的存儲(chǔ)器位置加載到定點(diǎn)(通用)中。 由于內(nèi)存訪問(wèn)比寄存器操作慢(即使在訪問(wèn)L1數(shù)據(jù)高速緩存時(shí)),因此在存儲(chǔ)過(guò)程中CPU停頓以完成后續(xù)加載。
注 :文件, “POWER ISA 2.06(POWER7)”(見(jiàn)相關(guān)信息 ),包含更多的信息。
大多數(shù)情況下,性能計(jì)數(shù)器事件會(huì)觸發(fā)中斷,從而使指令的PC地址保存在與執(zhí)行指令接近的位置。 這可能導(dǎo)致裝配注釋不完全準(zhǔn)確。 為了減輕這種現(xiàn)象,POWER4和更高版本具有一組有限的性能計(jì)數(shù)器,它們的名稱(chēng)為marked 。 標(biāo)記的指令將在每個(gè)時(shí)間范圍內(nèi)產(chǎn)生較少的事件; 但是,PC指令將準(zhǔn)確無(wú)誤,從而產(chǎn)生準(zhǔn)確的裝配注釋。 標(biāo)記的事件在由opcontrol -l獲取的OProfile計(jì)數(shù)器列表中具有PM_MRK前綴。
要仔細(xì)檢查分析,請(qǐng)觀看PM_MRK_LSU_REJECT_LHS計(jì)數(shù)器。 PM_MRK_LSU_REJECT_LHS和PM_LSU_REJECT_LHS這兩個(gè)計(jì)數(shù)器都監(jiān)視同一性能事件。 但是,標(biāo)記的計(jì)數(shù)器( PM_MRK_LSU_REJECT_LHS )將在每個(gè)時(shí)間范圍內(nèi)生成較少的事件,但具有更準(zhǔn)確的程序集注釋。 (請(qǐng)參見(jiàn)清單21。 )
清單21. PM_MRK_LSU_REJECT_LHS POWER7事件的性能記錄
$ perf record -C 0 -e rd082 taskset -c 0 ./hypot_bench_glibc $ perf report Events: 256K raw 0xd08264.61% hypot_bench_gli libm-2.12.so [.] __ieee754_hypot35.33% hypot_bench_gli libm-2.12.so [.] __GI___finite這將在清單22中生成程序集批注。
清單22. PM_MRK_LSU_REJECT_LHS POWER7事件的性能報(bào)告
: 00000080fc38b730 <.__ieee754_hypot>: [...]1.23 : 80fc38b7a8: c9 a1 00 70 lfd f13,112(r1)0.00 : 80fc38b7ac: f8 01 00 70 std r0,112(r1)32.66 : 80fc38b7b0: c8 01 00 70 lfd f0,112(r1) [...]0.00 : 80fc38b954: f8 01 00 70 std r0,112(r1)0.00 : 80fc38b958: e8 0b 00 00 ld r0,0(r11)0.00 : 80fc38b95c: 79 00 00 0e rldimi r0,r8,32,061.72 : 80fc38b960: c9 61 00 70 lfd f11,112(r1 [...]清單23中 ,另一個(gè)符號(hào)顯示了35%的具有類(lèi)似行為的已生成事件。
清單23.性能報(bào)告的更多亮點(diǎn)
: 00000080fc3a2610 <.__finitel>>0.00 : 80fc3a2610: d8 21 ff f0 stfd f1,-16(r1)100.00 : 80fc3a2614: e8 01 ff f0 ld r0,-16(r1)根據(jù)此信息,您的優(yōu)化工作可能是通過(guò)除去FP到INT的轉(zhuǎn)換來(lái)消除這些停頓。 POWER處理器具有快速高效的浮點(diǎn)執(zhí)行單元,因此無(wú)需使用定點(diǎn)指令執(zhí)行這些計(jì)算。 POWER當(dāng)前在GLIBC中使用的算法(sysdeps / powerpc / fpu / e_hypot.c)僅通過(guò)使用FP操作已刪除了所有LHS停頓。 結(jié)果是清單24中更簡(jiǎn)單的算法。
清單24. PowerPC GLIBC hypot源代碼
double __ieee754_hypot (double x, double y) {x = fabs (x);y = fabs (y);TEST_INF_NAN (x, y);if (y > x){double t = x;x = y;y = t;}if (y == 0.0 || (x / y) > two60){return x + y;}if (x > two500){x *= twoM600;y *= twoM600;return __ieee754_sqrt (x * x + y * y) / twoM600;}if (y < twoM500){if (y <= pdnum){x *= two1022;y *= two1022;return __ieee754_sqrt (x * x + y * y) / two1022;}else{x *= two600;y *= two600;return __ieee754_sqrt (x * x + y * y) / two600;}}return __ieee754_sqrt (x * x + y * y); }TEST_INF_NAN宏是另一個(gè)較小的優(yōu)化,它在開(kāi)始進(jìn)一步的FP操作之前測(cè)試數(shù)字是NaN還是INFINITY(這是由于對(duì)NaN和INFINITY進(jìn)行的操作會(huì)引發(fā)FP異常,并且函數(shù)規(guī)范不允許這樣做)。 在POWER7上, isinf和isnan函數(shù)調(diào)用已由編譯器優(yōu)化為FP指令,并且不會(huì)生成額外的函數(shù)調(diào)用,而在較舊的處理器(POWER6和較舊的處理器)上,它將生成對(duì)相應(yīng)函數(shù)的調(diào)用。 優(yōu)化基本上是相同的實(shí)現(xiàn),但是內(nèi)聯(lián)以避免函數(shù)調(diào)用。
最后,比較這兩種實(shí)現(xiàn),執(zhí)行以下簡(jiǎn)單測(cè)試。 使用和不使用新算法重新編譯GLIBC,并比較每次基準(zhǔn)測(cè)試的總時(shí)間。 清單25是默認(rèn)的GLIBC實(shí)現(xiàn)結(jié)果:
清單25.帶有默認(rèn)GLIBC假設(shè)的基準(zhǔn)
$ /usr/bin/time ./hypot_bench_glibc INF_CASE : elapsed time: 14:994339 NAN_CASE : elapsed time: 14:707085 TWO60_CASE : elapsed time: 12:983906 TWO500_CASE : elapsed time: 10:589746 TWOM500_CASE : elapsed time: 11:215079 NORMAL_CASE : elapsed time: 15:325237 79.80user 0.01system 1:19.81elapsed 99%CPU (0avgtext+0avgdata 151552maxresident)k 0inputs+0outputs (0major+48minor)pagefaults 0swaps優(yōu)化的版本結(jié)果如清單26所示 :
清單26.優(yōu)化的GLIBC假設(shè)基準(zhǔn)
$ /usr/bin/time ./hypot_bench_glibc INF_CASE : elapsed time: 4:667043 NAN_CASE : elapsed time: 5:100940 TWO60_CASE : elapsed time: 6:245313 TWO500_CASE : elapsed time: 4:838627 TWOM500_CASE : elapsed time: 8:946053 NORMAL_CASE : elapsed time: 6:245218 36.03user 0.00system 0:36.04elapsed 99%CPU (0avgtext+0avgdata 163840maxresident)k 0inputs+0outputs (0major+50minor)pagefaults 0swaps這是最終性能提高了100%以上,將基準(zhǔn)時(shí)間縮短了一半。
結(jié)論
帶有硬件計(jì)數(shù)器配置文件的性能評(píng)估是一種功能強(qiáng)大的工具,可以了解工作負(fù)載在特定處理器上的行為方式,并提示在哪里進(jìn)行性能優(yōu)化。 最新的POWER7處理器具有數(shù)百個(gè)可用的性能計(jì)數(shù)器,因此我們提出了一個(gè)簡(jiǎn)單的模型,該模型將工作負(fù)載映射到CPU停頓。 了解POWER7 CBM有點(diǎn)復(fù)雜,因此我們還介紹了簡(jiǎn)化它的Linux工具。 性能評(píng)估的策略集中在如何查找熱點(diǎn) ,如何理解應(yīng)用程序的內(nèi)存模式以及如何使用POWER7 CBM。 最后,我們使用了最近對(duì)GLIBC內(nèi)的三角函數(shù)進(jìn)行的優(yōu)化來(lái)解釋用于生成優(yōu)化代碼的性能分析。
附錄
根據(jù)GNU自由文檔許可版本1.3,已授予復(fù)制,分發(fā)和/或修改本文檔的權(quán)限; 沒(méi)有不變的部分,沒(méi)有前封面文字,也沒(méi)有后封面文字。
翻譯自: https://www.ibm.com/developerworks/opensource/library/l-evaluatelinuxonpower/index.html
linux power
總結(jié)
以上是生活随笔為你收集整理的linux power_评估Linux on POWER的性能的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 为什么各种年鉴都不公布
- 下一篇: linux 其他常用命令