最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

MegPeak—讓你更懂你的處理器

2022-12-05 15:35 作者:曠視天元MegEngine  | 我要投稿

作者:陳其友 | 曠視 MegEngine 架構(gòu)師

MegPeak 介紹

在這個(gè)算力需求爆炸的大背景下,如何發(fā)揮出已有硬件的最大算力變得非常重要,直觀一點(diǎn)是:我們需要對(duì)現(xiàn)有算法針對(duì)特定的處理器進(jìn)行極致的性能優(yōu)化,盡量滿(mǎn)足目前 AI 算法對(duì)算力高要求。為了能夠做到極致的性能優(yōu)化,我們可能的方向有:

  • 優(yōu)化算法,使得算法能夠在滿(mǎn)足準(zhǔn)確度前提下,訪存和計(jì)算量盡量小

  • 優(yōu)化程序,使得實(shí)現(xiàn)這些算法的程序最大限度發(fā)揮處理器性能

在優(yōu)化程序的過(guò)程中,首先要解決的問(wèn)題是:如何評(píng)估我們程序發(fā)揮了處理器幾成的算力,以及進(jìn)一步優(yōu)化空間和優(yōu)化方向。

為了更懂我們的處理器,MegEngine 團(tuán)隊(duì)開(kāi)發(fā)了一個(gè)工具?MegPeak,可以幫助開(kāi)發(fā)人員進(jìn)行性能評(píng)估,開(kāi)發(fā)指導(dǎo)等,目前已經(jīng)開(kāi)源到?GitHub:https://github.com/MegEngine/MegPeak

MegPeak 功能

通過(guò) MegPeak 用戶(hù)可以測(cè)試目標(biāo)處理器:

  • 指令的峰值帶寬

  • 指令延遲

  • 內(nèi)存峰值帶寬

  • 任意指令組合峰值帶寬

雖然上面的部分信息可以通過(guò)芯片的數(shù)據(jù)手冊(cè)查詢(xún)相關(guān)數(shù)據(jù),然后結(jié)合理論計(jì)算得到,但是很多情況下無(wú)法獲取目標(biāo)處理器詳盡的性能文檔,另外通過(guò) MegPeak 進(jìn)行測(cè)量更直接和準(zhǔn)確,并且可以測(cè)試特定指令組合的峰值帶寬。

MegPeak 使用方法

使用方法參考 MegPeak 的?Readme?文檔:https://github.com/MegEngine/MegPeak#build

MegPeak 使用示例

測(cè)試 ArmV8 上通用指令峰值和延遲,編譯完成之后,在目標(biāo)處理器上執(zhí)行 megpeak,得到:

如上圖所示,MegPeak 可以精確測(cè)試出 CPU 上每條指令的計(jì)算峰值以及延遲周期。OpenCL 上將測(cè)試出不同數(shù)據(jù)類(lèi)型進(jìn)行訪存的 Local Memory,Global Memory 的帶寬,以及 int/float 不同數(shù)據(jù)類(lèi)型進(jìn)行計(jì)算的峰值。這些數(shù)值將有效的指導(dǎo)我們?cè)u(píng)估目前程序的性能,并繪制 RoofLine,將可以幫助用戶(hù)診斷出阻塞程序主要因素,是訪存或者計(jì)算,具體使用分析方法將在后面介紹。

MegPeak 原理

MegPeak 測(cè)試的主要參數(shù)是

  • CPU 不同指令的計(jì)算峰值,以及指令延遲,以及內(nèi)存帶寬

  • OpenCL 中不同內(nèi)存的數(shù)據(jù)訪存帶寬,以及不同計(jì)算數(shù)據(jù)類(lèi)型的計(jì)算峰值

要了解 MegPeak 是如何測(cè)試出上面這些性能數(shù)據(jù),并且做到和數(shù)據(jù)手冊(cè)上查詢(xún)到盡量一致,因此需要讀者了解下面 CPU 流水線相關(guān)細(xì)節(jié)。

處理器流水線

現(xiàn)代處理器為了增加指令的吞吐,引入了指令流水線,指令流水線可以將一條指令的執(zhí)行過(guò)程劃分為多個(gè)階段,經(jīng)典的 5 級(jí)流水線有:取指令,翻譯指令,執(zhí)行指令,訪問(wèn)寄存器,寫(xiě)回?cái)?shù)據(jù),這 5 個(gè)階段,處理器中執(zhí)行每個(gè)階段的物理單元獨(dú)立,因此理想狀態(tài)下,每個(gè)時(shí)鐘周期每個(gè)階段對(duì)應(yīng)的物理單元都能執(zhí)行一次對(duì)應(yīng)的操作,這樣就形成了流水線,這樣處理器每個(gè)時(shí)鐘周期就可以完成執(zhí)行一條指令。如下表所示,從第 5 個(gè)時(shí)鐘周期之后,每個(gè)時(shí)鐘周期都會(huì)完成一條指令執(zhí)行:

但是,流水線在實(shí)際執(zhí)行時(shí)候不可能一直這樣流暢的執(zhí)行下去,會(huì)存在以下的冒險(xiǎn),阻塞流水線。

  • 結(jié)構(gòu)冒險(xiǎn)——如果硬件無(wú)法同時(shí)支持指令的所有可能組合方式,就會(huì)出現(xiàn)資源沖突,從而導(dǎo)致結(jié)構(gòu)冒險(xiǎn)

  • 數(shù)據(jù)冒險(xiǎn)——流水線指令存在先后順序,如果一條指令取決于先前指令的結(jié)果,就可能導(dǎo)致數(shù)據(jù)冒險(xiǎn)

  • 控制冒險(xiǎn)——分支指令及其他改變程序計(jì)數(shù)器的指令實(shí)現(xiàn)流水化時(shí),可能導(dǎo)致控制冒險(xiǎn)

MegPeak 中測(cè)量處理器指令的計(jì)算峰值和延遲就是通過(guò)控制指令間的數(shù)據(jù)冒險(xiǎn),盡可能排除結(jié)構(gòu)冒險(xiǎn)和控制冒險(xiǎn)來(lái)實(shí)現(xiàn)的,因?yàn)?MegPeak 中需要通過(guò)寫(xiě) Code 來(lái)控制處理器的數(shù)據(jù)冒險(xiǎn),為了排除編譯器編譯 code 時(shí)候的優(yōu)化帶來(lái)的干擾,所以在 MegPeak 在測(cè)試中的核心代碼使用匯編來(lái)實(shí)現(xiàn)的。

測(cè)試指令峰值

為了測(cè)量處理器上一條指令的計(jì)算峰值,我們需要寫(xiě)出重復(fù)執(zhí)行這條指令,但是沒(méi)有任何冒險(xiǎn)的代碼,所以需要代碼控制數(shù)據(jù)冒險(xiǎn)和控制冒險(xiǎn)。

  • 消除數(shù)據(jù)冒險(xiǎn)----消除重復(fù)指令之間的數(shù)據(jù)依賴(lài),讓前后指令之間沒(méi)有下面的數(shù)據(jù)相關(guān),雖然 WAW,WRA 不是真正的數(shù)據(jù)相關(guān),處理器可能會(huì)使用寄存器重命名來(lái)解決,但是我們還是盡量不要寫(xiě)出這樣的數(shù)據(jù)相關(guān)。

    • 寫(xiě)后讀(RAW):上一條指令寫(xiě)入,下一條指令讀取寫(xiě)入數(shù)據(jù),這時(shí)候后一條指令需要等上一條指令運(yùn)行結(jié)束之后再運(yùn)行

    • 寫(xiě)后寫(xiě)(WAW):兩條指令前后寫(xiě)入同一個(gè)寄存器,這時(shí)候數(shù)據(jù)寫(xiě)入的先后順序很重要

    • 讀后寫(xiě)(WRA) :上一條指令讀取一個(gè)寄存器,下一條指令將新的數(shù)據(jù)寫(xiě)入這個(gè)寄存器,他們的順序也同樣很重要

  • 盡可能的消除控制冒險(xiǎn)----為了重復(fù)多次執(zhí)行同一條指令,我們可能會(huì)用循環(huán)來(lái)實(shí)現(xiàn),但是循環(huán)里面有分支,可能會(huì)造成控制冒險(xiǎn),所以我們需要盡可能的循環(huán)展開(kāi),讓一個(gè)循環(huán)里面執(zhí)行更多的數(shù)據(jù)無(wú)關(guān)的指令,但是這個(gè)數(shù)量會(huì)被處理器的寄存器數(shù)量限制。

下面是 MegPeak 測(cè)試 Arm64 上 fmla 指令計(jì)算峰值時(shí)候的核心 Code。

上面的內(nèi)嵌匯編代碼中,主要做了幾件事情

  • 初始化 0–19 號(hào) neon 寄存器為零,這一步不是必須的,但可以避免計(jì)算過(guò)程中出現(xiàn) nan 導(dǎo)致的潛在影響。

  • 創(chuàng)建主循環(huán),主循環(huán)中每條指令執(zhí)行,從對(duì)應(yīng)的寄存器讀取數(shù)據(jù),并執(zhí)行 fmla 指令,將計(jì)算結(jié)果寫(xiě)到相同的寄存器中,同一條指令內(nèi)部沒(méi)有數(shù)據(jù)相關(guān)。

這里有一個(gè)問(wèn)題需要解釋?zhuān)瑸槭裁催x擇 20 個(gè)寄存器:

  • 如果寄存器選擇太少,上一次循環(huán)可能還沒(méi)有計(jì)算完成,下一次循環(huán)讀取相同的寄存器,可能造成數(shù)據(jù)相關(guān),因此循環(huán)里面執(zhí)行的指令條數(shù)需要大于指令延遲和處理器單個(gè)周期內(nèi)能夠執(zhí)行的指令數(shù)的乘積,但是我們不知道這條指令延遲,但是可以估計(jì),除了特殊的指令,延遲一般不超過(guò) 10 個(gè)時(shí)鐘周期。

  • Arm64 有 32 個(gè) neon 寄存器,為什么不選擇 32 個(gè)寄存器,因?yàn)?20 個(gè)寄存器已經(jīng)可以避免數(shù)據(jù)和控制相關(guān)了,測(cè)試發(fā)現(xiàn)使用更多的寄存器影響很小。
    執(zhí)行上面的代碼,可以統(tǒng)計(jì)執(zhí)行的時(shí)間,加上可以提前通過(guò)指令的數(shù)目以及循環(huán)的次數(shù)計(jì)算出真正的計(jì)算量,因此便可以計(jì)算出指令的計(jì)算峰值。

測(cè)試指令延遲

為了測(cè)量處理器上一條指令的執(zhí)行延遲,我們需要寫(xiě)出重復(fù)執(zhí)行這條指令,并讓這些指令之間存在嚴(yán)格的數(shù)據(jù)冒險(xiǎn),盡量排除其他冒險(xiǎn)。

  • 制造數(shù)據(jù)冒險(xiǎn)----讓前后兩條指令之間的數(shù)據(jù)存在真正的數(shù)據(jù)依賴(lài)(RAW),即上一條指令的輸出為下一條指令的輸入

  • 盡可能的消除控制冒險(xiǎn)----同上

下面是 MegPeak 測(cè)試 Arm64 上 fmla 指令延遲的核心 Code。

上面的內(nèi)嵌匯編代碼中,主要將?

?這條指令重復(fù)了 20 次,這樣每條指令都依賴(lài)上一條指令的計(jì)算結(jié)果,所以存在嚴(yán)格的數(shù)據(jù)相關(guān)。

執(zhí)行代碼,統(tǒng)計(jì)執(zhí)行時(shí)間,通過(guò)執(zhí)行的指令條數(shù),可以計(jì)算出這條指令最終的延遲。

上面的代碼在 MegPeak 中實(shí)現(xiàn),不是這么直接,而是通過(guò)宏來(lái)實(shí)現(xiàn) code 的生成。

用 MegPeak 測(cè)到的數(shù)據(jù),可以用來(lái)干什么

MegPeak 可以測(cè)試出處理器的內(nèi)存帶寬,指令的理論計(jì)算峰值,指令的延遲等信息,因此可以幫助我們:

  • 繪制 Roofline Model 指導(dǎo)我們優(yōu)化模型性能

  • 評(píng)估程序的優(yōu)化空間

  • 探索指令組合的理論計(jì)算峰值

另外 MegPeak 還可以提供對(duì)理論的驗(yàn)證,如我們通過(guò)處理器頻率單核單周期指令發(fā)射數(shù)量每條指令執(zhí)行的計(jì)算量可以計(jì)算出理論計(jì)算峰值,然后我們可以通過(guò) MegPeak 進(jìn)行實(shí)際測(cè)量進(jìn)行驗(yàn)證。

繪制指令相關(guān)的 Roofline Model

Roofline 模型被大量的使用在高性能計(jì)算中,是評(píng)估算法的可優(yōu)化程度和優(yōu)化方向的重要工具。使用 MegPeak 可以繪制出更加具體的關(guān)于指令對(duì)應(yīng)的 Roofline 模型,如:在 CPU 中,不同的數(shù)據(jù)類(lèi)型,雖然訪存帶寬不會(huì)改變,但是計(jì)算峰值差距比較大,比如在 arm 上 float 的計(jì)算峰值和 int8 的計(jì)算峰值差距很大。

評(píng)估代碼優(yōu)化空間

在優(yōu)化具體算法的時(shí)候,可以通過(guò) MegPeak 測(cè)試出 kernel 里面的主要指令的最大峰值,如在 Arm 上優(yōu)化 fp32 Matmul 的時(shí)候,主要用到的指令是 fmla 指令,這時(shí)候可以測(cè)試程序?qū)嶋H運(yùn)行的峰值,如果指令的峰值和程序的峰值差距越小,說(shuō)明代碼優(yōu)化的越好。

另外,可以根據(jù)算法實(shí)現(xiàn)計(jì)算出計(jì)算量和訪存量,并使用 MegPeak 繪制出上面的 Roofline,通過(guò)計(jì)算實(shí)際的計(jì)算密度,然后再對(duì)應(yīng)到 Roofline 中,如果計(jì)算密度落在上圖中的綠色區(qū)域,說(shuō)明程序需要更多考慮優(yōu)化訪存,提供更優(yōu)的訪存模型,如分塊,提前 pack 數(shù)據(jù)等。如果計(jì)算強(qiáng)度的點(diǎn)落在灰色區(qū)域說(shuō)明,代碼已經(jīng)最優(yōu)了,如果還想進(jìn)一步提速,只能考慮從算法角度進(jìn)行優(yōu)化了,如:在卷積中使用?FFT,Winograd?等算法進(jìn)行優(yōu)化。

探索最優(yōu)指令組合

很多 Kernel 的優(yōu)化不是單純的某一條指令就可以衡量,可能需要多條指令的組合才能代表整個(gè) Kernel 的計(jì)算,因此我們需要探索如何組織這些指令使其達(dá)到處理器最優(yōu)的性能。下面列舉在 A53 小核優(yōu)化 fp32 Matmul 的過(guò)程中,由于 Matmul 是計(jì)算密集型算子,考慮通過(guò)多發(fā)射隱藏訪存指令的開(kāi)銷(xiāo),使用 MegPeak 配合進(jìn)行分析,探索如何組合指令實(shí)現(xiàn)盡可能多的多發(fā)射。

因?yàn)樾『松厦尜Y源有限,指令多發(fā)射有很多限制,

  • 首先使用 MegPeak 出測(cè)試 A53 上 fp32 的 fmla 指令的計(jì)算峰值,將其定義為 100% 峰值計(jì)算性能

  • 測(cè)試哪些指令組合可以支持雙發(fā)射

    • 在 MegPeak 中添加 vector load 和 fmla 1:1 組合的代碼,然后測(cè)試其峰值僅僅為 float 峰值的 36%,表明 Vector load 和 fmla 不能雙發(fā)射

    • 同樣可以測(cè)得通用寄存器 load 指令 ldr+fmla 的組合可以達(dá)到 float 峰值的 93%,說(shuō)明 ldr 可以和 fmla 雙發(fā)射

    • 同上可以測(cè)得 ins + fmla 能雙發(fā)射,ins + vector load 64 位 可以雙發(fā)射

  • 根據(jù) Matmul 最內(nèi)層 Kernel 的?計(jì)算原理,如最內(nèi)層 Kernel 的分塊大小是 8x12,那最內(nèi)層需要讀?。?0 個(gè) float 數(shù)據(jù),計(jì)算 24 次 fmla 計(jì)算

  • 結(jié)合上面的 MegPeak 測(cè)試的信息,我們需要找到用最少時(shí)鐘完成這:20 個(gè) float 數(shù)據(jù) load,和 24 次 fmla 數(shù)據(jù)計(jì)算的指令組合,因此需要將盡可能多的數(shù)據(jù) load 和 fmla 進(jìn)行雙發(fā)射,隱藏?cái)?shù)據(jù) load 的耗時(shí)

  • 最后的指令組合是:

    • 使用 vector load 64 指令 + ldr + ins 組合成為一個(gè) neon 寄存器數(shù)據(jù),因?yàn)?ldr 和 ins 都可以和 fmla 雙發(fā)射,把他們和 fmla 放在一起可以隱藏他們的耗時(shí)

    • 在這 3 條指令中穿插 fmla 指令,并盡可能解決數(shù)據(jù)依賴(lài)

根據(jù)上面的指令組合可以使得 Matmul 在小核上達(dá)到計(jì)算峰值的 70%左右。

總結(jié)

MegPeak 作為一個(gè)進(jìn)行高性能計(jì)算的輔助工具,能夠使得開(kāi)發(fā)人員輕松獲得目標(biāo)處理器的內(nèi)在的詳細(xì)信息,輔助進(jìn)行對(duì)代碼的性能評(píng)估,以及優(yōu)化方法設(shè)計(jì)。但是 MegPeak 也有一些需要豐富的方向:

  • 支持獲取更多的處理器性能數(shù)據(jù),如:L1,L2 cache 的大小,自動(dòng)探索各種指令組合的雙發(fā)射情況,并大概繪制出一個(gè)處理器后端的縮略圖。如:https://en.wikichip.org/w/images/5/57/cortex-a76_block_diagram.svg

  • 支持測(cè)量移動(dòng)端 OpenCL 的更多細(xì)節(jié)信息,如:warp size,local memory 大小等。

如果有同學(xué)對(duì)上面的功能感興趣,歡迎大家提交代碼。最后歡迎大家使用 MegPeak。

MegPeak—讓你更懂你的處理器的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
高雄县| 喀喇沁旗| 临汾市| 峡江县| 府谷县| 巴青县| 安岳县| 元朗区| 当雄县| 青岛市| 通道| 怀远县| 大方县| 凤翔县| 衡阳县| 金寨县| 大理市| 万山特区| 内黄县| 邻水| 马鞍山市| 前郭尔| 延寿县| 周至县| 疏勒县| 许昌市| 仙游县| 广汉市| 沁源县| 广南县| 同江市| 法库县| 响水县| 梅河口市| 永泰县| 台北市| 民勤县| 全南县| 宾阳县| 蛟河市| 绍兴市|