新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 高效的C編程之: 函數調用

        高效的C編程之: 函數調用

        作者: 時間:2013-09-30 來源:網絡 收藏

        本文引用地址:http://www.104case.com/article/257016.htm

        14.9.4嵌套優化

        注意

        嵌套優化(Tail-Calloptimization)只適用于armcc。編譯時如果使用-g或-debug選項,編譯器自動關閉該功能。

        一個函數如果在其結束時調用了另一個函數,則編譯器使用B指令調轉到被調用函數,而非BL指令。這樣就避免了一級不必要的函數返回。圖14.3顯示了嵌套優化的調用過程。

        圖14.3嵌套優化過程

        當編譯時使用-O1或-O2選項時,編譯器都執行這種嵌套優化。需要注意的是,當函數中引用了局部變量地址,由于指針別名問題的影響,即使函數在返回時調用了其他函數,編譯器也不會使用嵌套優化。

        下面通過一個例子來分析嵌套優化是如何提高代碼執行效率的。

        externintfunc2(int);

        intfunc1(inta,intb)

        {if(a>b)

        return(func2(a-b));

        else

        return(func2(b-a));

        }

        編譯后的代碼如下所示。

        func1

        CMPa1,a2

        SUBLEa1,a2,a1

        SUBGTa1,a1,a2

        Bfunc2

        首先,func1中使用B指令代替BL指令,不用擔心lr寄存器被破壞,減少了對寄存器壓棧保護操作。另外,程序直接從func2返回到調用func1的函數,減少一次函數返回。如果說正常的指令調用過程為:

        BL+BL+MOVpc,lr+MOVpc,lr

        那么經過嵌套優化的過程就可以表示為:

        BL+BL+MOVpc,lr

        這樣,總的開銷將減少25%。

        14.9.5單純子函數

        所謂單純子函數(PureFunctions)是指那些函數返回值只和調用參數有關。換句話說,就是如果調用函數的參數相同,那么函數的返回結果也相同。如果程序中存在這樣的函數,可以在函數定義時使用_pure進行聲明,這樣在程序編譯時編譯器會根據函數的調用情況對其進行優化。

        下面的例子顯示了當函數用_pure聲明時,編譯器對其所做的優化。

        程序源碼文件如下。

        intsquare(intx)

        {

        returnx*x;

        }

        intf(intn)

        {

        returnsquare(n)+square(n)

        }

        編譯后的結果如下。

        square

        MOVa2,a1

        MULa1,a2,a2

        MOVpc,lr

        f

        STMDBsp!,{lr}

        MOVa3,a1

        BLsquare

        MOVa4,a1

        MOVa1,a3

        BLsquare

        ADDa1,a4,a1

        LDMIAsp!,{pc}

        上面的程序中,square函數為“單純子函數”,當使用_pure聲明該函數時編譯器在調用該函數時,將對程序進行優化。

        聲明的方法和編譯后的結果如下所示。

        __pureintsquare(intx)

        {

        returnx*x;

        }

        f

        STMDBsp!,{lr}

        BLsquare

        MOVa1,a1,LSL#1

        LDMIAsp!,{pc}

        從編譯后的代碼中可以看到,用_pure聲明的函數在f函數中只調用了一次。

        雖然“單純子函數”可以提高代碼執行效率,但同時也會帶來一些負面影響。比如,在“單純子函數”中,不能直接或間接訪問內存地址。所以在程序中使用“單純子函數”時要特別小心。

        另外,還可以使用#pragma聲明“單純子函數”,下面的代碼顯示了它的聲明過程。

        #pragmano_side_effects

        /*functiondefinition*/

        #pragmaside_effects



        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 嘉善县| 花垣县| 荥经县| 姚安县| 轮台县| 米脂县| 巴南区| 大连市| 梁平县| 汾阳市| 蓬莱市| 札达县| 怀柔区| 延边| 德清县| 永济市| 奉贤区| 龙门县| 黄大仙区| 石家庄市| 定陶县| 上犹县| 江山市| 出国| 阿勒泰市| 兴义市| 鹤壁市| 顺平县| 贺兰县| 浪卡子县| 旌德县| 徐水县| 新丰县| 台南市| 分宜县| 南召县| 大兴区| 繁峙县| 兖州市| 桂东县| 盖州市|