官术网_书友最值得收藏!

1.3.1 如何測(cè)得CPU的浮點(diǎn)峰值性能

一顆CPU的理論浮點(diǎn)峰值性能反映了這顆CPU的最大浮點(diǎn)處理能力,通常也稱為CPU的吞吐量。一般來(lái)說(shuō),CPU浮點(diǎn)峰值統(tǒng)計(jì)的浮點(diǎn)計(jì)算類型只包含乘法和加法(包括減法)。這主要是因?yàn)椋焊↑c(diǎn)乘法和加法構(gòu)成了很多廣泛使用且基礎(chǔ)的重要算法的核心,如矩陣乘法、FFT等。

本節(jié)以Intel Sandy Bridge(簡(jiǎn)稱SNB)和Ivy Bridge(簡(jiǎn)稱IVB)架構(gòu)的CPU為例,介紹如何計(jì)算理論浮點(diǎn)峰值,并實(shí)測(cè)出該峰值。這里以單精度峰值為例,雙精度一般為單精度的1/2,測(cè)試方法也相同。

計(jì)算理論浮點(diǎn)峰值實(shí)際上就是計(jì)算CPU每個(gè)處理核心一個(gè)周期可以處理的浮點(diǎn)乘法和浮點(diǎn)加法的次數(shù)。查看Intel的手冊(cè)知道,在SNB和IVB架構(gòu)下,浮點(diǎn)乘法的延遲是5,吞吐量是1;浮點(diǎn)加法的延遲是3,吞吐量是1。可以得到SNB和IVB的單精度浮點(diǎn)峰值計(jì)算公式如下:

單精度浮點(diǎn)峰值=CPU核心數(shù)×頻率×(8Mul+8Add)

市面上一顆普通的Intel i3 2100的SNB處理器,雙核,頻率是3.1GHz,那么它的單精度浮點(diǎn)峰值就是2×3.1GHz×(8+8)=99.2GFLOPS。

AVX中的vmulps和vaddps指令就是計(jì)算256位單精度浮點(diǎn)乘法和加法的指令。要同時(shí)發(fā)揮乘法和加法的性能,就要求相鄰的乘法和加法指令沒(méi)有依賴關(guān)系,而SNB和IVB架構(gòu)一個(gè)時(shí)鐘周期最多可以發(fā)射4條指令,故處理器的指令發(fā)射能力不會(huì)成為瓶頸。了解了這些信息之后,相應(yīng)的測(cè)試程序也就容易寫了,匯編代碼如代碼清單1-5所示。

代碼清單1-5 測(cè)試SNB CPU峰值性能程序


mov $0x1000000, %rax           @ 0x1000000是循環(huán)次數(shù),根據(jù)需要可以改大或改小
vxorps %ymm0, %ymm0, %ymm0
vxorps %ymm1, %ymm1, %ymm1
vxorps %ymm2, %ymm2, %ymm2
vxorps %ymm3, %ymm3, %ymm3
loop:
vmulps %ymm1, %ymm1, %ymm0
vaddps %ymm3, %ymm3, %ymm2
subq $0x1, %rax
jne loop

代碼中前5行是初始化寄存器狀態(tài),設(shè)置rax為循環(huán)計(jì)數(shù)器,主要在loop循環(huán)內(nèi)不斷執(zhí)行兩條乘法和加法指令。由于SNB架構(gòu)對(duì)add和sub類指令也可以做微指令融合,所以subq和jne兩條指令可以與vmulps和vaddps在同一個(gè)周期發(fā)射。vmulps和vaddps之間沒(méi)有數(shù)據(jù)依賴,前后兩次循環(huán)之間也沒(méi)有數(shù)據(jù)依賴。

其余的工作就是開(kāi)啟和處理器核數(shù)同樣多的C語(yǔ)言線程調(diào)用,且每個(gè)線程綁定到不同的處理器核,然后調(diào)用這個(gè)函數(shù),用計(jì)時(shí)器記錄多線程執(zhí)行的時(shí)間。利用公式16×線程數(shù)×循環(huán)次數(shù)/時(shí)間,即可得到這顆處理器的實(shí)測(cè)GFLOPS峰值性能。在筆者的i3 2100 SNB處理器上實(shí)測(cè)得到97.87GFLOPS,很接近理論峰值99.2GFLOPS。

實(shí)際上,代碼清單1-5在X86處理器上能夠獲得接近峰值的性能有以下原因:

1)寄存器重命名機(jī)制。前后兩次循環(huán)都寫入同一個(gè)寄存器,這是一個(gè)典型的“寫后寫”依賴。如果沒(méi)有寄存器重命名機(jī)制的幫助,那么后一條指令就必須等待前一條指令執(zhí)行完成,形成了一條“完美”的關(guān)于寄存器的數(shù)據(jù)依賴鏈,那么就不可能接近峰值。

2)預(yù)測(cè)執(zhí)行。如果沒(méi)有預(yù)測(cè)執(zhí)行機(jī)制,則下次循環(huán)只能等待循環(huán)條件判斷執(zhí)行完成之后才能開(kāi)始執(zhí)行,這樣就會(huì)基于判斷條件指令形成一條依賴鏈(控制依賴),也就不可能獲得接近峰值的性能。

3)4發(fā)射。循環(huán)內(nèi)部至少有4條指令,如果發(fā)射能力小于4的話,那么發(fā)射能力就成為了瓶頸。比如假設(shè)處理器的指令發(fā)射能力為2,那么一次循環(huán)需要2個(gè)周期才能發(fā)射完,也不可能達(dá)到接近峰值的水平。

4)4條指令發(fā)射到不同的流水線上。如果有兩個(gè)指令發(fā)射到同一條流水線上,那么這兩條指令就必須相互等待(只有一條執(zhí)行完成,另一條才有可能得到執(zhí)行)。而若4條指令發(fā)射到不同的流水線上的話,那么這4條指令可以同時(shí)在不同的流水線上執(zhí)行,即不存在結(jié)構(gòu)化瓶頸。

注意 這個(gè)方法在同一顆處理器上測(cè)出的單核和多核性能,不一定呈線性倍數(shù)關(guān)系,原因在于,現(xiàn)在Intel的處理器很多都有turbo boost技術(shù),會(huì)根據(jù)負(fù)載給處理器自動(dòng)超頻,一般單核負(fù)載時(shí)超頻更高,多核時(shí)較低,甚至完全不超頻。所以除非關(guān)掉turbo boost,或者在沒(méi)有turbo boost支持的處理器上測(cè)試,才可能呈現(xiàn)倍數(shù)關(guān)系。

Intel最新的Haswell架構(gòu)處理器開(kāi)始支持256位的浮點(diǎn)融合乘加指令FMA,即將乘法和加法融合在一條指令中(即a×b+c)。FMA指令的吞吐量是2,延遲是5。由于Intel設(shè)計(jì)的是FMA3指令,即三操作數(shù)的FMA指令,所以在a、b和c三個(gè)輸入向量中,會(huì)有一個(gè)作為輸出結(jié)果。這就導(dǎo)致我們?cè)趯慒MA的峰值測(cè)試程序時(shí),無(wú)法滿足前后兩個(gè)循環(huán)的數(shù)據(jù)無(wú)依賴特征這個(gè)條件,導(dǎo)致下一個(gè)循環(huán)需要等待上一個(gè)循環(huán)的結(jié)果計(jì)算完畢才開(kāi)始執(zhí)行。而FMA的延遲有5個(gè)周期,即兩個(gè)循環(huán)之間的延遲需要5個(gè)周期,這會(huì)極大地拖慢處理速度,也造成了流水線的浪費(fèi)。

為了解決這個(gè)問(wèn)題,測(cè)試程序需要在一次循環(huán)內(nèi)添加足夠多的數(shù)據(jù)無(wú)依賴關(guān)系的FMA指令,將流水線填滿,下次循環(huán)到同一條指令時(shí),上個(gè)循環(huán)的該指令延遲已經(jīng)結(jié)束,可以立即發(fā)射。由于一個(gè)周期可以同時(shí)發(fā)射兩條FMA指令,且延遲是5,那么需要在一個(gè)循環(huán)內(nèi)加入10條FMA指令方能填滿執(zhí)行流水線,如代碼清單1-6所示。

代碼清單1-6 測(cè)試Haswell處理器峰值性能


loop:
vfmadd231ps %ymm0, %ymm0, %ymm0      @ 周期0,5,10,15…發(fā)射
vfmadd231ps %ymm1, %ymm1, %ymm1      @ 周期0,5,10,15…發(fā)射
vfmadd231ps %ymm2, %ymm2, %ymm2      @ 周期1,6,11,16…發(fā)射
vfmadd231ps %ymm3, %ymm3, %ymm3      @ 周期1,6,11,16…發(fā)射
vfmadd231ps %ymm4, %ymm4, %ymm4      @ 周期2,7,12,17…發(fā)射
vfmadd231ps %ymm5, %ymm5, %ymm5      @ 周期2,7,12,17…發(fā)射
vfmadd231ps %ymm6, %ymm6, %ymm6      @ 周期3,8,13,18…發(fā)射
vfmadd231ps %ymm7, %ymm7, %ymm7      @ 周期3,8,13,18…發(fā)射
vfmadd231ps %ymm8, %ymm8, %ymm8      @ 周期4,9,14,19…發(fā)射
vfmadd231ps %ymm9, %ymm9, %ymm9      @ 周期4,9,14,19…發(fā)射
subq $0x1, %rax
jne loop

本節(jié)以這個(gè)例子作為基礎(chǔ),主要闡釋了浮點(diǎn)運(yùn)算的量化準(zhǔn)則和流水線技術(shù),并初步展示了達(dá)到高浮點(diǎn)吞吐量的基本方法。下面3節(jié)中的例子將會(huì)由簡(jiǎn)入難地展示實(shí)際問(wèn)題在Intel x86處理器下性能優(yōu)化的各種方法和實(shí)戰(zhàn)技巧。

主站蜘蛛池模板: 海林市| 和龙市| 潜山县| 凌源市| 郓城县| 类乌齐县| 义马市| 巴中市| 玉门市| 巴楚县| 华蓥市| 铜梁县| 盐源县| 鹤庆县| 炉霍县| 岑巩县| 若尔盖县| 涟源市| 卫辉市| 县级市| 彩票| 水富县| 乐安县| 武清区| 忻城县| 民权县| 平山县| 安庆市| 太原市| 开鲁县| 万山特区| 虎林市| 东平县| 墨竹工卡县| 津市市| 台南市| 潜山县| 团风县| 清苑县| 临安市| 辰溪县|