欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標(biāo)題: STM32H7/cotex M內(nèi)核 匯編,內(nèi)嵌匯編小技巧 [打印本頁]

作者: UH502    時間: 2025-11-6 02:39
標(biāo)題: STM32H7/cotex M內(nèi)核 匯編,內(nèi)嵌匯編小技巧
以下作為我個使用cotex  M7內(nèi)核統(tǒng)計的一些特性:

一  內(nèi)核行為分析
實例代碼1:
FPU_Test: //double FPU_Test (double a_mul,double b_mul,double c_add);
        
        
        PUSH{R4-R7}
        MOV R0, #1024        //減少循環(huán)次數(shù),避免緩存影響
    // 初始化完全獨立的寄存器組

    LDR R1,=8234
        MOV R6,R0
        MOV R7,R1
        PLI [LR]
        
FPU_Test_Loop_Opt:
    // 8組完全獨立的 VFMA 操作
    VFMA.F32 S2, S1, S0      // 組1
        SMLAL  R3,R2,R1,R0
    VFMA.F32 S3, S1, S0      // 組2 - 完全獨立
        SUBS R4,R4, #1
        SHADD16 R5,R5,R0
        SMLAL  R3,R2,R1,R0
    VFMA.F32 S4, S1, S0      // 組3 - 完全獨立
        SHADD16 R4,R4,R1
        SUBS R5,R5, #1
        SMLAL  R3,R2,R1,R0
    VFMA.F32 S5, S1, S0    // 組4 - 完全獨立
        SHADD16 R5,R5,R0
        SUBS R4,R4, #1
        SMLAL  R3,R2,R1,R0
    VFMA.F32 S6, S1, S0   // 組5 - 完全獨立
    SUBS R0,R0, #1
    BNE FPU_Test_Loop_Opt

        
        

        POP{R4-R7}
    BX LR


以上為keilv5  MDK V5.23 編譯器語法
1:使用VFMA(浮點區(qū)域指令)與使用SMLAL(整數(shù)區(qū)域指令)能夠讓處理器進(jìn)行雙發(fā)射(在cotex  M7權(quán)威手冊里亦有記載)
但是,注意需注意順序即:
    VFMA.F32 S2, S1, S0      // 組1
    SMLAL  R3,R2,R1,R0


      VFMA.F32 S4, S1, S0      // 組3 - 完全獨立
      SHADD16 R4,R4,R1
是能夠正常雙發(fā)射
    VFMA.F32 S2, S1, S0      // 組1
    SMLAL  R3,R2,R1,R0


      SHADD16 R4,R4,R1
      VFMA.F32 S4, S1, S0      // 組3 - 完全獨立
以上只能單發(fā)射,而不能雙發(fā)射

      SHADD16 R4,R4,R1
      SUBS R5,R5, #1
      SMLAL  R3,R2,R1,R0
      VFMA.F32 S5, S1, S0    // 組4 - 完全獨立
   以上可以雙發(fā)射
總結(jié)為:在使用浮點+整數(shù)指令時,下一條指令如果需要使用整數(shù)并且需要使用寄存器,那么MCU則不支持雙發(fā)射,如果為浮點,即可成功雙發(fā)射.
若持續(xù)為整數(shù)指令,那么在數(shù)據(jù)無依賴的情況下,即可雙發(fā)射,否者只能單發(fā)射,或者阻塞 (均不包含除法指令)
1     針對于除法指令,在mcu上能不用就不用,無符號/有符號整數(shù)除法平均會消耗10個周期左右,除非你的結(jié)果較小,例如小于256.那么可以在較短的時間里得出結(jié)果,對于雙精度浮點除法,通常需要14-16個時鐘周期,單精度需要8-12個周期.除法指令是阻塞運行的,不支持單周期的吞吐量.除法比較特殊,即使數(shù)據(jù)無依賴也不行
2    在cotex-m7內(nèi)核上,大部分都會有支持雙精度浮點,但是,雙精度浮點一般比單精度慢2-8倍,不同指令有著不同的效率,如VADD.F64就最快,2周期的吞吐量,基本與VADD.F32 的單周期差不了太多,對于像VFMA.F32(實例代碼中的指令)為單周期吞吐量.  VFMA.F64不支持單周期吞吐量,執(zhí)行一條需要7個周期,并且不支持與其他指令雙發(fā)射,包括大部分的.F64的運算指令(像VMOV.F64這種執(zhí)行時間為2周期,與雙精度與單精度無關(guān),執(zhí)行周期按位寬/32bit)都不支持與其他指令雙發(fā)射


二    性能優(yōu)化:
對于需要性能優(yōu)化的場景來說,手動添加(C#) __ASM    volatile{  "PLI  [這里填C里的一個變量]");用于提前預(yù)加載(提示內(nèi)核等會兒要使用)需要執(zhí)行的指令,可以在跳轉(zhuǎn)后更快的執(zhí)行,通常用于執(zhí)行動態(tài)代碼,例如:
__ASM volatile (
                        "push{r0,r1}\n"
                        "MOV R0,0X01 \n"
                        "ISB SY\n"
                        "PLI [R0]\n"
                        "ISB SY\n"
                        "pop {r0,r1}\n"
                );



__ASM  volatile (
                        "push {r0-r3,r12,lr} \n"
                        "MOV R0,0X01 \n"
                       "BLX R0 \n"
                        "pop {r0-r3,r12,lr} \n"
    );
中,將動態(tài)代碼存放于ITCM內(nèi)存中,代碼就是實例代碼1,存放地址0x00
對于需要跳轉(zhuǎn)動態(tài)代碼時,保存寄存器是一個必不可少的的操作,通常使用堆棧保存,通常建議堆棧始終為8字節(jié)對齊(在cotex  M系列內(nèi)核權(quán)威手冊里亦有記載) 所以在使用push的時候,建議一次性壓入兩個寄存器(64位)保持一直為8字節(jié)對齊.對于未對其的情況下,我也測試過了,首先效率會下降,對齊的情況,入棧8個字節(jié)僅需一個周期,無阻塞的發(fā)射,即可執(zhí)行接下來的指令,未對其情況下,與使用STM  SP!{ }是等效的,需要1個周期解析指令+2個周期存入數(shù)據(jù).

      其次未8字節(jié)對齊容易導(dǎo)致未定義行為,進(jìn)入HardFault_Handler,這個問題隱藏的很隱蔽,使用Jlink單步調(diào)試是無法復(fù)現(xiàn)問題.(我沒記錯的話,權(quán)威手冊里應(yīng)該有記載,不過容易忽略,這里就提個醒)
      對于地址跳轉(zhuǎn),一定要保證,需要跳轉(zhuǎn)的地址的最低位一定要為1, 例如你需要跳轉(zhuǎn)到0x0800346,那么你實際要寫入PC指針的地址一定是0x0800347,而不是0x0800346,否則也會導(dǎo)致未定義行為,進(jìn)入HardFault_Handler,同樣使用jlink無法復(fù)現(xiàn),單步無法發(fā)現(xiàn)問題.


先記錄到這里,如有新的勘誤點會在更新,附件為cotex  M4系列內(nèi)核匯編編程手冊,全冊中文,對于初學(xué)者來說很有用處

STM32F3與F4系列Cortex M4內(nèi)核編程手冊_中文版.pdf

6.71 MB, 下載次數(shù): 0, 下載積分: 黑幣 -5






歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1