日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

NEON編程中的一些常見優(yōu)化技巧

安芯教育科技 ? 來源:安謀科技學(xué)堂 ? 作者:安謀科技學(xué)堂 ? 2022-12-12 09:11 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1.簡介

讀過上一篇文章“ARM NEON快速上手指南”之后,相信你已經(jīng)對ARM NEON編程有了基本的認(rèn)識。但在真正利用ARM NEON優(yōu)化程序性能時,還有很多編程技巧和注意事項(xiàng)。本文將結(jié)合本人的一些開發(fā)經(jīng)歷,介紹NEON編程中的一些常見優(yōu)化技巧,希望能對用戶在NEON實(shí)際開發(fā)中有些借鑒意義。

2.NEON優(yōu)化技術(shù)

在利用NEON優(yōu)化程序時,有下述幾項(xiàng)比較通用的優(yōu)化技巧。

2.1 降低數(shù)據(jù)依賴性

在ARM v7-A NEON指令通常需要3~9個指令周期,NEON指令比ARM指令需要更多周期數(shù)。因此,為了減少指令延時,最好避免將當(dāng)前指令的目的寄存器當(dāng)作下條指令的源寄存器。如下例所示:

// C代碼
float SumSquareError_C(const float* src_a, const float* src_b, int count) 
{
  float sse = 0u;
  int i;
  for (i = 0; i < count; ++i) {
    float diff = src_a[i] - src_b[i];
    sse += (float)(diff * diff);
  }
  return sse;
}
// NEON實(shí)現(xiàn)一
float SumSquareError_NEON1(const float* src_a, const float* src_b, int count)
{
  float sse;
  asm volatile (
    "veor    q8, q8, q8                        
"
    "veor    q9, q9, q9                        
"
    "veor    q10, q10, q10                     
"
    "veor    q11, q11, q11                     
"

  "1:                                          
"
    "vld1.32     {q0, q1}, [%0]!               
"
    "vld1.32     {q2, q3}, [%0]!               
"
    "vld1.32     {q12, q13}, [%1]!             
"
    "vld1.32     {q14, q15}, [%1]!             
"
    "subs       %2, %2, #16                    
"
    // q0, q1, q2, q3 是vsub的目的地寄存器.
    // 也是vmla的源寄存器。
    "vsub.f32   q0, q0, q12                    
"
    "vmla.f32   q8, q0, q0                     
"

    "vsub.f32   q1, q1, q13                    
"
    "vmla.f32   q9, q1, q1                     
"

    "vsub.f32   q2, q2, q14                    
"
    "vmla.f32   q10, q2, q2                    
"

    "vsub.f32   q3, q3, q15                    
"
    "vmla.f32   q11, q3, q3                    
"
    "bgt        1b                             
"

    "vadd.f32   q8, q8, q9                     
"
    "vadd.f32   q10, q10, q11                  
"
    "vadd.f32   q11, q8, q10                   
"
    "vpadd.f32  d2, d22, d23                   
"
    "vpadd.f32  d0, d2, d2                     
"
    "vmov.32    %3, d0[0]                      
"
    : "+r"(src_a),
      "+r"(src_b),
      "+r"(count),
      "=r"(sse)
    :
    : "memory", "cc", "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11","q12", "q13","q14", "q15");
  return sse;
}
// NEON實(shí)現(xiàn)二
float SumSquareError_NEON2(const float* src_a, const float* src_b, int count)
{
  float sse;
  asm volatile (
    "veor    q8, q8, q8                        
"
    "veor    q9, q9, q9                        
"
    "veor    q10, q10, q10                     
"
    "veor    q11, q11, q11                     
"

  "1:                                          
"
    "vld1.32     {q0, q1}, [%0]!               
"
    "vld1.32     {q2, q3}, [%0]!               
"
    "vld1.32     {q12, q13}, [%1]!             
"
    "vld1.32     {q14, q15}, [%1]!             
"
    "subs       %2, %2, #16                    
"
    "vsub.f32   q0, q0, q12                    
"
    "vsub.f32   q1, q1, q13                    
"
    "vsub.f32   q2, q2, q14                    
"
    "vsub.f32   q3, q3, q15                    
"
    
    "vmla.f32   q8, q0, q0                     
"
    "vmla.f32   q9, q1, q1                     
"
    "vmla.f32   q10, q2, q2                    
"
    "vmla.f32   q11, q3, q3                    
"
    "bgt        1b                             
"

    "vadd.f32   q8, q8, q9                     
"
    "vadd.f32   q10, q10, q11                  
"
    "vadd.f32   q11, q8, q10                   
"
    "vpadd.f32  d2, d22, d23                   
"
    "vpadd.f32  d0, d2, d2                     
"
    "vmov.32    %3, d0[0]                      
"
    : "+r"(src_a),
      "+r"(src_b),
      "+r"(count),
      "=r"(sse)
    :
    : "memory", "cc", "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "q12", "q13","q14", "q15");
  return sse;
}

在NEON實(shí)現(xiàn)一中,我們把目的寄存器立刻當(dāng)作源寄存器;在NEON實(shí)現(xiàn)二中,我們重新排布了指令,并給予目的寄存器盡量多的延時。經(jīng)過測試實(shí)現(xiàn)二比實(shí)現(xiàn)一快30%。由此可見,降低數(shù)據(jù)依賴性對于提高程序性能有重要意義。一個好消息是編譯器能自動調(diào)整NEON intrinsics以降低數(shù)據(jù)依賴性。這個利用NEON intrinsics的一個很大優(yōu)勢。

2.2 減少跳轉(zhuǎn)

NEON指令集沒有跳轉(zhuǎn)指令,當(dāng)需要跳轉(zhuǎn)時,我們需要借助ARM指令。在ARM處理器中,分支預(yù)測技術(shù)被廣泛使用。但是一旦分支預(yù)測失敗,懲罰還是比較高的。因此我們最好盡量減少跳轉(zhuǎn)指令的使用。其實(shí),在有些情況下,我們可以用邏輯運(yùn)算來代替跳轉(zhuǎn),如下例所示:

// C實(shí)現(xiàn)
if( flag )
{
        dst[x * 4]     = a;
        dst[x * 4 + 1] = a;
        dst[x * 4 + 2] = a;
        dst[x * 4 + 3] = a;
}
else
{
        dst[x * 4]     = b;
        dst[x * 4 + 1] = b;
        dst[x * 4 + 2] = b;
        dst[x * 4 + 3] = b;
}
// NEON實(shí)現(xiàn)
//dst[x * 4]     = (a&Eflag) | (b&~Eflag);
//dst[x * 4 + 1] = (a&Eflag) | (b&~Eflag);
//dst[x * 4 + 2] = (a&Eflag) | (b&~Eflag);
//dst[x * 4 + 3] = (a&Eflag) | (b&~Eflag);

VBSL qFlag, qA, qB

ARM NEON指令集提供了下列指令來幫助用戶實(shí)現(xiàn)上述邏輯實(shí)現(xiàn):

? VCEQ, VCGE, VCGT, VCLE, VCLT……

? VBIT, VBIF, VBSL……

減少跳轉(zhuǎn),不僅僅是在NEON中使用的技巧,是一個比較通用的問題。即使在C程序中,這個問題也是值得注意的。

2.3 其它技巧

在ARM NEON編程時,一種功能有時有多種實(shí)現(xiàn)方式,但是更少的指令不總是意味著更好的性能,要依據(jù)測試結(jié)果和profiling數(shù)據(jù),具體問題具體分析。下面列出來我遇到的一些特殊情況。2.3.1 浮點(diǎn)累加指令通常情況下,我們會用VMLA/VMLS來代替VMUL + VADD/ VMUL + VSUB,這樣使用較少的指令,完成更多的功能。但是與浮點(diǎn)VMUL相比,浮點(diǎn)VMLA/VMLS具有更長的指令延時,如果在指令延時中間不能插入其它計算的情況下,使用浮點(diǎn)VMUL + VADD/ VMUL + VSUB反而具有更好的性能。一個真實(shí)例子就是Ne10庫函數(shù)的浮點(diǎn)FIR函數(shù)。代碼片段如下所示:

實(shí)現(xiàn)1:在兩條VMLA指令之間,僅有VEXT指令。而根據(jù)指令延時表,VMLA需要9個周期。

實(shí)現(xiàn)2:對于qAcc0,依然存在指令延時。但是VADD/VMUL只需要5個周期。下列代碼中周期n粗略地表示了指令執(zhí)行需要的周期數(shù)。與實(shí)現(xiàn)1相比,實(shí)現(xiàn)2節(jié)省了6個周期。性能測試也表明實(shí)現(xiàn)2具有更好的性能。

實(shí)現(xiàn) 1: VMLA
VEXT qTemp1,qInp,qTemp,#1
VMLA qAcc0,qInp,dCoeff_0[0]-- cycle 0

VEXT qTemp2,qInp,qTemp,#2
VMLA qAcc0,qTemp1,dCoeff_0[1] -- cycle 9

VEXT qTemp3,qInp,qTemp,#3
VMLA qAcc0,qTemp2,dCoeff_1[0] -- cycle 18

VMLA qAcc0,qTemp3,dCoeff_1[1] -- cycle 27
得到最終結(jié)果 qAcc0需要36個指令周期。
實(shí)現(xiàn) 2:  VMUL+VADD
VEXT qTemp1,qInp,qTemp,#1
VMLA qAcc0,qInp,dCoeff_0[0] ]-- cycle 0
VMUL qAcc1,qTemp1,dCoeff_0[1]

VEXT qTemp2,qInp,qTemp,#2
VMUL qAcc2,qTemp2,dCoeff_1[0]
VADD qAcc0, qAcc0, qAcc1-- cycle 9

VEXT qTemp3,qInp,qTemp,#3
VMUL qAcc3,qTemp3,dCoeff_1[1]
VADD qAcc0, qAcc0, qAcc2-- cycle 14 

VADD qAcc0, qAcc0, qAcc3-- cycle 19
得到最終結(jié)果 qAcc0需要24個指令周期。
與實(shí)現(xiàn)1相比,三條VADD指令需要6個發(fā)射指令周期??偣残枰?30個指令周期。

modules/dsp/NE10_fir.neon.s:line 195

指令延時請參考下表:

Name Format Cycles Result
VADD/VSUB/VMUL Qd,Qn,Dm 2 5
VMLA/VMLS Qd,Qn,Dm 2 9

表格來源于Cortex-A9 NEON Media Processing Engine Revision: r4p1 Technical Reference Manual: 3.4.8。

表格中:? Cycles:指令發(fā)射時間

? Result:指令執(zhí)行時間

2.4 小結(jié)

總結(jié)起來,NEON的優(yōu)化技巧主要有以下幾點(diǎn)

? 盡量利用指令執(zhí)行延時,合理安排指令順序

? 少用跳轉(zhuǎn)

? 注意cache命中率

審核編輯:郭婷


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • ARM
    ARM
    +關(guān)注

    關(guān)注

    135

    文章

    9589

    瀏覽量

    393799
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5620

    瀏覽量

    130455

原文標(biāo)題:Arm NEON學(xué)習(xí)(二)優(yōu)化技術(shù)

文章出處:【微信號:Ithingedu,微信公眾號:安芯教育科技】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    AR和MR光波導(dǎo)器件耦合光柵的優(yōu)化

    在上周的通訊,我們強(qiáng)調(diào)了分析基于光波導(dǎo)的增強(qiáng)和混合現(xiàn)實(shí)(AR & MR)設(shè)備的一些挑戰(zhàn)。 本周,我們將繼續(xù)深入討論這個話題,看看光波導(dǎo)系統(tǒng)耦合光柵的優(yōu)化。由于它們的尺寸小和自由參數(shù)
    發(fā)表于 04-27 08:16

    如何使用 powerquad 加速器一些功能以及 CMSIS 原始實(shí)現(xiàn)一些功能?

    )。 如何使用 powerquad 加速器一些功能以及 CMSIS 原始實(shí)現(xiàn)一些功能。 Example: I do not want to call arm_mat_tran
    發(fā)表于 04-03 06:37

    變頻器應(yīng)用的一些技巧

    變頻器作為現(xiàn)代工業(yè)控制的核心設(shè)備,其應(yīng)用范圍已從傳統(tǒng)的電機(jī)調(diào)速擴(kuò)展到節(jié)能改造、自動化生產(chǎn)線、新能源等領(lǐng)域。隨著技術(shù)的迭代,如何充分發(fā)揮變頻器性能并規(guī)避常見問題,成為工程師關(guān)注的焦點(diǎn)。以下從選型配置、參數(shù)調(diào)試、故障排查等維度,結(jié)合行業(yè)實(shí)踐案例,系統(tǒng)梳理變頻器的應(yīng)用技巧。
    的頭像 發(fā)表于 03-25 16:31 ?219次閱讀

    爬壁機(jī)器人磁鐵的一些常見問題

    爬壁機(jī)器人近幾年比較火,它是類能夠在垂直墻面、天花板、傾斜表面上移動和作業(yè)的特種機(jī)器人,今天我們不聊其它,只聊下關(guān)于磁吸附應(yīng)用的磁鐵,以下是小編整理的關(guān)于爬壁機(jī)器人中磁鐵的一些常見
    的頭像 發(fā)表于 01-09 10:06 ?460次閱讀
    爬壁機(jī)器人磁鐵的<b class='flag-5'>一些</b><b class='flag-5'>常見</b>問題

    CW32系統(tǒng)有哪些常見問題?

    在CW32系統(tǒng),可能會遇到一些常見問題,包括但不限于: 重復(fù)定義函數(shù):例如在a.c里定義了函數(shù)void func(),在b.c里也定義了個void func()。這會導(dǎo)致編譯時出
    發(fā)表于 12-15 06:47

    關(guān)于六類網(wǎng)線一些問題的解答

    今天我們就圍繞網(wǎng)友一些常見的關(guān)于六類網(wǎng)線的問題進(jìn)行下匯總式解答: 問 六類網(wǎng)線可以當(dāng)電源用嗎? 答 六類網(wǎng)線并不是設(shè)計用于傳輸電力的電纜,因此般不建議將其用于電源傳輸。 盡管六類網(wǎng)
    的頭像 發(fā)表于 12-09 11:13 ?787次閱讀

    貼片電容精度J±5%的一些詳細(xì)知識

    貼片電容精度J±5%表示電容的實(shí)際值與標(biāo)稱值之間的偏差范圍在±5%以內(nèi) ,以下是關(guān)于貼片電容精度J±5%的一些詳細(xì)知識: 、精度等級含義 J±5% :字母“J”在貼片電容的標(biāo)識通常表示標(biāo)稱精度
    的頭像 發(fā)表于 11-20 14:38 ?1013次閱讀
    貼片電容精度J±5%的<b class='flag-5'>一些</b>詳細(xì)知識

    蜂鳥E203的浮點(diǎn)指令集F的一些實(shí)現(xiàn)細(xì)節(jié)

    周期。 總結(jié) 本文介紹的內(nèi)容是為了完成基礎(chǔ)功能:對蜂鳥E203 RISC-V內(nèi)核的微架構(gòu)實(shí)現(xiàn)進(jìn)行優(yōu)化,在添加F拓展的過程一些記錄。
    發(fā)表于 10-24 08:57

    Vivado浮點(diǎn)數(shù)IP核的一些設(shè)置注意點(diǎn)

    : 總結(jié) 本文介紹的內(nèi)容是為了完成基礎(chǔ)功能:對蜂鳥E203 RISC-V內(nèi)核的微架構(gòu)實(shí)現(xiàn)進(jìn)行優(yōu)化,在添加F拓展的過程一些記錄。
    發(fā)表于 10-24 06:25

    在Ubuntu20.04系統(tǒng)訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型的一些經(jīng)驗(yàn)

    本帖欲分享在Ubuntu20.04系統(tǒng)訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型的一些經(jīng)驗(yàn)。我們采用jupyter notebook作為開發(fā)IDE,以TensorFlow2為訓(xùn)練框架,目標(biāo)是訓(xùn)練個手寫數(shù)字識別的神經(jīng)網(wǎng)絡(luò)
    發(fā)表于 10-22 07:03

    射頻工程師需要知道的一些常見轉(zhuǎn)接頭

    ,是由于轉(zhuǎn)接頭的損壞造成的,而且有些接頭的連接固定的方式不對,每次修好的儀器,過去后客戶又按照他們原來的方式去擰緊了。特別是在一些生產(chǎn)型的企業(yè),由于操作人員流動性比較
    的頭像 發(fā)表于 08-06 17:39 ?1586次閱讀
    射頻工程師需要知道的<b class='flag-5'>一些</b><b class='flag-5'>常見</b>轉(zhuǎn)接頭

    如何優(yōu)化編程電源控制環(huán)路參數(shù)?

    時環(huán)路相位裕度僅25°,輸出電壓振蕩(頻率10kHz)。 優(yōu)化措施:在補(bǔ)償網(wǎng)絡(luò)增加個小電容(10pF),引入個高頻極點(diǎn)衰減振蕩;調(diào)整補(bǔ)償電容CCOMP?從10nF增至22nF,提
    發(fā)表于 07-02 15:56

    在低功耗藍(lán)牙產(chǎn)品開發(fā)的過程,會涉及到一些參數(shù)的選擇和設(shè)定,這些參數(shù)是什么意思,該如何設(shè)定呢?(藍(lán)牙廣播)

    在低功耗藍(lán)牙產(chǎn)品開發(fā)的過程,會涉及到一些參數(shù)的選擇和設(shè)定,這些參數(shù)是什么意思,該如何設(shè)定呢?在此介紹一些: 藍(lán)牙的廣播類型(Advertising Type) 可連接廣播(ADV_IND):允許
    發(fā)表于 06-25 18:25

    HarmonyOS優(yōu)化應(yīng)用內(nèi)存占用問題性能優(yōu)化

    應(yīng)用開發(fā)過程中注重內(nèi)存管理,積極采取措施來減少內(nèi)存占用,以優(yōu)化應(yīng)用程序的性能和用戶體驗(yàn)。 HarmonyOS提供了一些內(nèi)存管理的工具和接口,幫助開發(fā)者有效地管理內(nèi)存資源: onMemoryLevel接口
    發(fā)表于 05-21 11:27

    Debian和Ubuntu哪個好一些?

    兼容性對比Debian和Ubuntu哪個好一些,并為您揭示如何通過RAKsmart服務(wù)器釋放Linux系統(tǒng)的最大潛能。
    的頭像 發(fā)表于 05-07 10:58 ?1444次閱讀
    甘泉县| 淳化县| 土默特左旗| 晴隆县| 古田县| 辽阳市| 扶沟县| 娄底市| 吉水县| 大渡口区| 泽普县| 裕民县| 绥宁县| 游戏| 龙游县| 盐津县| 苍南县| 遂宁市| 南城县| 贵定县| 攀枝花市| 太仆寺旗| 泊头市| 桃源县| 浮梁县| 南京市| 孟连| 台北市| 万年县| 都安| 化德县| 微山县| 乌恰县| 大荔县| 江华| 偃师市| 浠水县| 霞浦县| 天峨县| 蒙城县| 平邑县|