<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 在Cortex-A8平臺下memcpy ARM/NEON匯編性能的測試

          在Cortex-A8平臺下memcpy ARM/NEON匯編性能的測試

          作者: 時間:2016-11-10 來源:網(wǎng)絡(luò) 收藏
          本文介紹了基于ARMv7架構(gòu)的Cortex-A8芯片(FreeScale i.MX51 / i.MX53/QualComm msm8x50 / msm7x30/Samsung s5pc100 / s5pc110/TI omap 3430 / omap 3730芯片)上采用C語言、ARM匯編和NEON匯編實現(xiàn)的memcpy的性能對比,并輸入分析了NEON指令(不同處理器的NEON內(nèi)存位寬從64-bit到128-bit不等)和cache的預(yù)取preload(preload engine指令)對性能的影響。最終結(jié)論表明1.在拷貝塊大小block size = 512B ~ 32K之間,有一個性能高臺,block size = 256K也有一個性能的轉(zhuǎn)折。這個特性體現(xiàn)了芯片32KB L1 / 256KB L2 cache的影響;2. NEON指令的性能總是要高于ARM指令的性能。隨著發(fā)展ARM/NEON指令之間性能差在縮小。交替使用ARM/NEON指令,性能往往要差于NEON版本;3.如果沒有很好的模型設(shè)計,軟件去干預(yù)cache的使用,很容易會造成性能的惡化; 4.在fit in cache條件下,Snapdragon平臺有最好的性能; 5.在out of cache條件下,s5pc110有最好的性能; 6.在同一個硬件平臺下,超頻對memory性能影響很小; 7.同一種的實現(xiàn),在不同的硬件平臺上都有不同的表現(xiàn)。沒有一種實現(xiàn)在所有平臺上是最好的。
          1. 前言

            在C run time library中,memcpy是重要的函數(shù),對應(yīng)用軟件的性能有著重要的影響。ARM芯片發(fā)展到Cortex-A8[1][2]架構(gòu),不但頻率有了很大提升,而且架構(gòu)設(shè)計有了很大地改進。其中增加的NEON指令,是類似于原先X86平臺下的MMX指令,是為多媒體而設(shè)計。但因為這類指令一次可以處理64-bit數(shù)據(jù),對memcpy函數(shù)性能提升也很有幫助。本文主要是測試采用NEON[2]指令的多種memcpy實現(xiàn),探討NEON指令和預(yù)取(preload)指令對性能的影響,以及在芯片優(yōu)化和工藝進步后,這些影響的變化趨勢。同時希望芯片設(shè)計人員在了解軟件實現(xiàn)的基礎(chǔ)上,給予一個知其然,也知其所以然的解釋,進而指導(dǎo)進一步提高性能的方向。

            本文引用地址:http://www.ex-cimer.com/article/201611/317414.htm
          2. 平臺介紹

            本次的測試平臺來源于筆者工作項目中接觸到的Cortex-A8平臺。見下面列表:

          • FreeScale i.MX51 / i.MX53
          • QualComm msm8x50 / msm7x30
          • Samsung s5pc100 / s5pc110
          • TI omap 3430 / omap 3730
          1. i.MX5 family

            i.MX5 family的介紹見[6][7]。其中i.MX535可以運行在800MHZ / 1000MHZ兩種頻率上。

          • i.MX515
            • freq: 800MHZ
            • cache size: 32KB/32KB I/D Cache and 256KB L2 Cache
            • cache line: 64-bit wide(NEON), 64-byte / line
          • i.MX535
          • freq: 800MHZ / 1000MHZ
          • cache size: 32KB/32KB I/D Cache and 256KB L2 Cache
          • cache line: 64-bit wide(NEON), 64-byte / line
          1. Snapdragon family

            Snapdragon的介紹見[8][9][10]。其中msm7x30可以運行在800MHZ / 1000MHZ兩種頻率上。此外Snapdragon cache特別之處是128-bit wide(NEON), 128-byte / line。標(biāo)準(zhǔn)Cortex-A8中,該數(shù)值為64-bit wide(NEON), 64-byte / line。這對性能有較大影響。

          • msm8x50
            • freq: 1000MHZ
            • cache size: 32KB/32KB I/D Cache and 256KB L2 Cache
            • cache line: 128-bit wide(NEON), 128-byte / line
          • msm7x30
            • freq: 800MHZ / 1000MHZ
            • cache size: 32KB/32KB I/D Cache and 256KB L2 Cache
            • cache line: 128-bit wide(NEON), 128-byte / line
          1. s5pc family

            s5pc family參考平臺見[11]。

          • s5pc100
            • freq: 665MHZ
            • cache size: 32KB/32KB I/D Cache and 256KB L2 Cache
            • cache line: 64-bit wide(NEON), 64-byte / line
          • s5pc110
            • freq: 1000MHZ
            • cache size: 32KB/32KB I/D Cache and 512KB L2 Cache
            • cache line: 64-bit wide(NEON), 64-byte / line
          1. omap3 family

            omap3 family參考平臺見[12][13][14]。

          • omap3430
            • freq: 550MHZ
            • cache size: 16KB/16KB I/D Cache and 256KB L2 Cache
            • cache line: 64-bit wide(NEON), 64-byte / line
          • omap3730
            • freq: 1000MHZ
            • cache size: 32KB/32KB I/D Cache and 256KB L2 Cache
            • cache line: 64-bit wide(NEON), 64-byte / line
          1. memcpy實現(xiàn)介紹

            memcpy的實現(xiàn)在ARM平臺上的發(fā)展有3類版本:

          2. C語言版本
          3. ARM匯編版本
          4. NEON匯編版本

            ARM公司的文檔[4]對memcpy的實現(xiàn)有很好描述。有人[5][19][20]還進一步闡述了實現(xiàn)原理和技巧。簡述如下:

          • NEON指令一次可以處理64-bit數(shù)據(jù),效率更高。
          • NEON架構(gòu)與L1/L2 cache都有直連,在OS層級enable后,可以獲得更好的性能。
          • ARM / NEON的pipeline有可能異步處理,交替使用ARM / NEON指令有可能獲得更好的性能。
          • 在一次循環(huán)中,用盡可能多的寄存器copy更多的數(shù)據(jù),保證pipeline有更好的效率。目前一次最大處理塊為128-byte。
          • 對cache的操作有講究。
            • memcpy屬于一次掃瞄無回溯的操作,對于cache采用預(yù)取(preload)策略可以提高hit rate。所以匯編版本中一定會使用pld指令提示ARM預(yù)先把cache line填充好。
            • pld指令中的offset很有講究。一般為64-byte的倍數(shù)。在ARMv5TE平臺是一個循環(huán)用一個pld指令。在Cortex-A8平臺上速度更快,需要一個循環(huán)用2~3個pld指令填充cache line。這樣一個循環(huán)消費2~3個時鐘周期換得cache hit rate提高,效果是值得的。
            • 進一步的,Cortex-A8架構(gòu)提供了preload engine指令,可以讓軟件更深地影響cache,以便讓cache hit rate得到提高。不過要在用戶空間使用ple指令,需要在OS中打補丁開放權(quán)限。

          1. C語言版本

            C語言版本主要是做對比。采用兩個實現(xiàn):

          2. 32-bit wide copy。后面標(biāo)記為in32_cpy。
          3. 16-byte wide copy。后面標(biāo)記為vec_cpy。這個實現(xiàn)的技巧是采用gcc的向量擴展"__attribute__ ((vector_size(16)))",在C語言層級實現(xiàn)16-byte wide copy,將具體實現(xiàn)交給編譯器。

            值得注意的事情是,編譯器不會主動插入pld指令。因為編譯器無法判斷應(yīng)用對內(nèi)存的訪問模式。

          4. ARM匯編版本

            ARM匯編版本也主要是做對比。采用兩個實現(xiàn):

          5. Siarhei Siamashka實現(xiàn)[15]。后面標(biāo)記為arm9_memcpy。他是為Nokia N770做的優(yōu)化。
          6. Nicolas Pitre實現(xiàn)[16]。后面標(biāo)記為armv5te_memcpy。這是目前glibc里面缺省的arm memcpy實現(xiàn)。
          7. NEON匯編版本

            NEON匯編版本采用四個實現(xiàn):

          8. M?ns Rullg?rd實現(xiàn)[19]。這是一個128-byte-align block的最簡單的實現(xiàn)。沒有判斷不是128-byte align的情況。因此不是實用的版本。但通過這類實現(xiàn),可以考察memcpy性能的極限。他總共提供4種實現(xiàn)。
          9. 全ARM匯編的實現(xiàn)。后面標(biāo)記為memcpy_arm。此外,筆者還將其中的pld指令去掉,做為對比試驗,考察pld指令的影響。后面標(biāo)記為memcpy_arm_nopld。
          10. 全NEON匯編的實現(xiàn)。后面標(biāo)記為memcpy_neon。此外,筆者還將其中的pld指令去掉,做為對比試驗,考察pld指令的影響。后面標(biāo)記為memcpy_neon_nopld。
          11. ARM / NEON指令交替使用的實現(xiàn)。后面標(biāo)記為memcpy_armneon。此外,筆者還將其中的pld指令去掉,做為對比試驗,考察pld指令的影響。后面標(biāo)記為memcpy_armneon_nopld。
          12. ple + NEON的實現(xiàn)。后面標(biāo)記為memcpy_ple_neon。此外,筆者還將其中的NEON指令換成ARM指令,做為對比試驗,考察ple指令對ARM/NEON指令的影響。后面標(biāo)記為memcpy_ple_arm。因為這個實現(xiàn)需要對linux kernel打補丁,在omap3430平臺上沒有成功。在Snapdragon平臺上更換kernel有些麻煩,所以也沒有測試。
          13. CodeSourcery實現(xiàn)[17]。這是CodeSourcery toolchain中的glibc里面的實現(xiàn)。也分兩種實現(xiàn)。
          14. ARM實現(xiàn)。后面標(biāo)記為memcpy_arm_codesourcery。筆者還將其中的pld指令去掉,做為對比試驗,考察pld指令的影響。后面標(biāo)記為memcpy_arm_codesourcery_nopld。
          15. NEON實現(xiàn)。后面標(biāo)記為memcpy_neon_codesourcery。這也是Android bionic里面采用的NEON實現(xiàn)。筆者還將其中的pld指令去掉,做為對比試驗,考察pld指令的影響。后面標(biāo)記為memcpy_neon_codesourcery_nopld。
          16. QualComm實現(xiàn)[18]。后面標(biāo)記為memcpy_neon_qualcomm。這是QualComm在Code Aurora Forum中為Snapdragon平臺開發(fā)的優(yōu)化版本。主要是對8660/8650A平臺的優(yōu)化。這個版本的特點是針對L2 cache line size=128bytes而設(shè)計,pld offset設(shè)置得特別大。結(jié)果在其它Cortex-A8平臺上沒有效果。所以筆者將pld offset改為M?ns Rullg?rd實現(xiàn)的數(shù)值。筆者還將其中的pld指令去掉,做為對比試驗,考察pld指令的影響。后面標(biāo)記為memcpy_neon_qualcomm_nopld。
          17. Siarhei Siamashka實現(xiàn)[20]。后面標(biāo)記為memcpy_neon_siarhei。這是Siarhei Siamashka向glibc提交的NEON版本,沒有被glibc采納。但是在MAEMO項目中得到采用。這個版本的特點是pld offset是從小到大增長的,以期望適應(yīng)block size的變化。
          18. 測試方案介紹

            測試方案十分簡單。參考了movial memory tester的實現(xiàn)[21]。執(zhí)行步驟如下:

          19. 先對每個實現(xiàn)進行正確性的驗證。主要方法是以隨機的block size & offset,填充隨機的內(nèi)容,然后執(zhí)行memcpy操作,然后再用系統(tǒng)的memcmp函數(shù)對兩塊內(nèi)存做校驗。
          20. 然后對每個實現(xiàn)以不同的block size調(diào)用400次。如果total copy size < 1MB,則增加count直到滿足要求。對總操作計時。
          21. 以total copy size / total copy time公式計算memcpy bandwidth。

            上述提到的block size = 2^n ( 7 <= n <= 23 )。

            此外,這個測試程序運行在openembedded-gpe軟件系統(tǒng)中。QualComm / Samsung硬件平臺只提供Android軟件系統(tǒng),要更換到GPE系統(tǒng)有些麻煩,則采用chroot方式進行測試。不論是哪種軟件平臺,都是進入到圖形系統(tǒng)后,靜置,等待黑屏,然后再進行測試。

            下表是運行環(huán)境的統(tǒng)計。

            硬件平臺

            軟件環(huán)境

            imx51 800MHZ

            openembedded-gpe

            imx53 1000MHZ

            openembedded-gpe

            imx53 800MHZ

            openembedded-gpe

            msm7230 1000MHZ

            Android + chroot

            msm7230 800MHZ

            Android + chroot

            msm8250 1000MHZ

            Android + chroot

            omap3430 550MHZ

            openembedded-gpe

            omap3730 1000MHZ

            openembedded-gpe

            s5pc100 665MHZ

            Android + chroot

            s5pc110 1000MHZ

            Android + chroot

            下表是測試項目的統(tǒng)計。

            實現(xiàn)方案

            i.MX51

            i.MX53

            Snapdragon

            s5pc1xx

            omap3430

            omap3730

            int32_cpy

            YES

            YES

            YES

            YES

            YES

            YES

            vec_cpy

            YES

            YES

            YES

            YES

            YES

            YES

            arm9_memcpy

            YES

            YES

            YES

            YES

            YES

            YES

            armv5te_memcpy

            YES

            YES

            YES

            YES

            YES

            YES

            memcpy_arm

            YES

            YES

            YES

            YES

            YES

            YES

            memcpy_arm_nopld

            YES

            NO

            YES

            YES

            YES

            YES

            memcpy_neon

            YES

            YES

            YES

            YES

            YES

            YES

            memcpy_neon_nopld

            YES

            NO

            YES

            YES

            YES

            YES

            memcpy_armneon

            YES

            YES

            YES

            YES

            YES

            YES

            memcpy_ple_arm

            YES

            YES

            N/A

            YES

            N/A

            YES

            memcpy_ple_neon

            YES

            YES

            N/A

            YES

            N/A

            YES

            memcpy_arm_codesourcery

            YES

            YES

            YES

            YES

            YES

            YES

            memcpy_arm_codesourcery_nopld

            YES

            NO

            YES

            YES

            YES

            YES

            memcpy_neon_codesourcery

            YES

            YES

            YES

            YES

            YES

            YES

            memcpy_neon_codesourcery_nopld

            YES

            NO

            YES

            YES

            YES

            YES

            memcpy_neon_qualcomm

            YES

            YES

            YES

            YES

            YES

            YES

            memcpy_neon_qualcomm_nopld

            YES

            NO

            YES

            YES

            YES

            YES

            memcpy_neon_siarhei

            YES

            YES

            YES

            YES

            YES

            YES

            注1:因為i.MX53 EVK板子發(fā)生故障,未能測試所有no pld的測試項。

            注2:在給omap3430打開preload engine后,測試產(chǎn)生非法指令錯,未能測試ple的測試項。

            注3:要替換Snapdragon kernel有些麻煩,未能測試ple的測試項。

          22. 測試結(jié)果與分析

            下面的圖表限于頁面大小不能很好地顯示細節(jié)。具體的數(shù)據(jù)和大圖可到數(shù)據(jù)表文檔中查看。

          23. 各個硬件平臺上各種實現(xiàn)的表現(xiàn)

          24. imx51 800MHZ

          25. imx53 1000MHZ

          26. imx53 800MHZ

          27. msm7230 1000MHZ

          28. msm7230 800MHZ

          29. msm8250 1000MHZ

          30. omap3430 550MHZ

          31. omap3730 1000MHZ

          32. s5pc100 665MHZ

          33. s5pc110 1000MHZ

            1. 小結(jié)

          34. 在block size = 512B ~ 32K之間,有一個性能高臺,block size = 256K也有一個性能的轉(zhuǎn)折。
          35. 這個特性體現(xiàn)了32KB L1 / 256KB L2 cache的影響。
          36. 小于512B的性能不佳,可能與函數(shù)調(diào)用,函數(shù)開始的塊對齊技巧造成的損耗有關(guān),也可能與block size太小,cache沒有準(zhǔn)備好函數(shù)就結(jié)束了有關(guān)。
          37. 文檔[]對memcpy的實現(xiàn)還是有指導(dǎo)意義的。但隨著芯片內(nèi)部的優(yōu)化和工藝的提升,有些規(guī)則發(fā)生了變化。
          38. NEON指令的性能總是要高于ARM指令的性能。但交替使用ARM/NEON指令并不總是帶來性能的提升。隨著發(fā)展ARM/NEON指令之間性能差在縮小。
          39. pld指令的作用越來越小。在較老的芯片上,如omap3430,采用pld指令后,同一個實現(xiàn)可以有50%的性能提升。在較新的芯片上,如msm7230/s5pc110上,性能基本沒有區(qū)別,甚至同一個實現(xiàn)沒有pld指令后,性能稍稍有些提升。這也許是因為pld指令沒有效果,倒反在每個循環(huán)中浪費了時鐘周期造成的。
          40. 采用ple指令的實現(xiàn)的性能令人大失所望。這也說明如果沒有很好的模型設(shè)計,軟件去干預(yù)cache的使用,很容易會造成性能的惡化。
          41. Snapdragon平臺有最好的cache性能。超出cache后,各種實現(xiàn)(包括C語言實現(xiàn))的性能基本一致,也很高效。這也許是Snapdragon平臺13-stage load/store pipeline[][]的設(shè)計造成的。這個特性對高級語言是有好處的。因為編程不可能在很多地方采用匯編語言。這樣開發(fā)人員就不必過多地考慮匯編優(yōu)化,依賴編譯器就可以了。
          42. s5pc110平臺有最好的平均性能。超出cache后,NEON實現(xiàn)的性能最好,基本保持一條水平線。
          43. 在small/big block size下各個硬件平臺的表現(xiàn)

            性能因為block size分為fit in cache / out of cache兩種表現(xiàn),所以做兩個剖面做對比分析。

          • 8K block size。體現(xiàn)fit in cache時的性能。
          • 8M block size。體現(xiàn)out of cache時的性能。
          1. M?ns Rullg?rd的實現(xiàn)

            因為M?ns Rullg?rd的實現(xiàn)最簡單,除了一個循環(huán)體外,沒有其它判斷代碼,可以認為是體現(xiàn)平臺速度極限的實現(xiàn)。

          2. ARM的實現(xiàn)

          3. NEON的實現(xiàn)

          4. 小結(jié)

          5. NEON指令的性能總是要高于ARM指令的性能。隨著發(fā)展ARM/NEON指令之間性能差在縮小。
          6. 交替使用ARM/NEON指令,在fit in cache條件下性能要差于NEON版本。在out of cache條件下,兩個版本性能基本一樣。
          7. 在fit in cache條件下,Snapdragon平臺有最好的性能。超過第二名s5pc110大約為43%。
          8. 在out of cache條件下,s5pc110有最好的性能。超過第二名omap3730大約為57%。
          9. 在同一個硬件平臺下,超頻(如i.MX53 800/1000MHZ & msm7x30 800/1000MHZ)對memory性能影響很小。
          10. 實用ARM/NEON實現(xiàn)在各個硬件平臺的表現(xiàn)

            通過同一種實現(xiàn)在不同硬件平臺上性能的對比,結(jié)合上一節(jié)的圖表,可以評價一種實現(xiàn)的平均性能,也就是適應(yīng)性。

          11. ARM的實現(xiàn)

          12. NEON的實現(xiàn)

          13. 小結(jié)

          14. 同一種的實現(xiàn),在不同的硬件平臺上都有不同的表現(xiàn)。沒有一種實現(xiàn)在所有平臺上是最好的。
          15. Codesourcery版本,包括ARM/NEON版本,有很好的適應(yīng)性。不愧是做toolchain的公司。
          16. Siarhei Siamashka的NEON版本也有很好的適應(yīng)性。NOKIA的技術(shù)實力也很強。這哥們好像也是pixman項目里面做NEON優(yōu)化的主力。
          17. Qualcomm版本只適合Snapdragon平臺。期待以后能在msm8660以及后續(xù)的芯片上進行測試。
          18. 總結(jié)

          19. 在block size = 512B ~ 32K之間,有一個性能高臺,block size = 256K也有一個性能的轉(zhuǎn)折。這個特性體現(xiàn)了32KB L1 / 256KB L2 cache的影響。
          20. NEON指令的性能總是要高于ARM指令的性能。隨著發(fā)展ARM/NEON指令之間性能差在縮小。交替使用ARM/NEON指令,性能往往要差于NEON版本。
          21. 如果沒有很好的模型設(shè)計,軟件去干預(yù)cache的使用,很容易會造成性能的惡化。
          22. 在fit in cache條件下,Snapdragon平臺有最好的性能。
          23. 在out of cache條件下,s5pc110有最好的性能。
          24. 在同一個硬件平臺下,超頻對memory性能影響很小。
          25. 同一種的實現(xiàn),在不同的硬件平臺上都有不同的表現(xiàn)。沒有一種實現(xiàn)在所有平臺上是最好的。
          26. 進一步的測試

            因為在Cortex-A8系列芯片里,NEON模塊是必有的。而在Cortex-A9系列芯片里,NEON模塊是可選的。因為NEON模塊會影響到die size,因而影響功耗和成本。因此有些Cortex-A9芯片,如Nvidia Tegra250,沒帶有NEON模塊。那么有無NEON模塊會對軟件性能造成什么樣的影響呢?



          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();