當前位置:吉日网官网 - 傳統節日 - 如何優化C++程序代碼編寫

如何優化C++程序代碼編寫

第壹招:空間換時間的計算機程序最大的矛盾是空間和時間的矛盾。那麽從這個角度考慮程序的效率,我們就有了1的絕招來解決問題——用空間換時間。例如,字符串的賦值:

方法A:通常的方法。

#定義?萊恩。32

夏爾?string1?[LEN];

memset?(string1,0,LEN);

strcpy?(string1,“這個?是嗎?答?舉例!!");

方法b:

const?夏爾?string2[LEN]?=“這個?是嗎?答?例子!”;

夏爾?*?CP;

cp?=?string2?;使用時可以用指針直接操作。

從上面的例子可以看出,A和B的效率是不可比的。同樣的存儲空間,B可以直接用指針操作,而A需要調用兩個字符函數來完成。b的缺點是靈活性不如A,當壹個字符串的內容需要頻繁改變時,A的靈活性更好;如果采用方法B,需要預存很多字符串,占用大量內存,但是實現了程序執行的高效率。

如果系統的實時性要求很高,還有點內存的話,那麽我推薦妳用這壹招。

第二招:用宏代替函數。這也是第壹招的變體。函數和宏的區別在於,宏占用大量空間,而函數占用時間。妳需要知道的是,函數調用使用系統的堆棧來保存數據。如果編譯器中有堆棧檢查選項,壹些匯編語句會被嵌入到函數的頭部來檢查當前的堆棧。同時,函數調用時CPU還要保存和還原當前場景,進行堆棧壓入和堆棧彈回操作,所以函數調用需要壹定的CPU時間。宏沒有這個問題。宏只是作為預寫好的代碼嵌入到當前程序中,不會產生函數調用,所以只是占用空間,尤其是頻繁調用同壹個宏的時候。

例子如下:

方法c:

#定義?bwMCDR2_ADDRESS?四

#定義?bsMCDR2_ADDRESS?17

int?BIT_MASK(int?__bf)

{

回歸?((1U?& lt& lt?(bw?##?__bf))?-?1)& lt;& lt?(bs?##?_ _ BF);

}

作廢?SET_BITS(int?_ _夏令時,

int?__bf,?int?__val)

{

__dst?=?((__dst)?& amp?~(BIT_MASK(__bf))?|

(((__val)?& lt& lt?(bs?##?__bf))

& amp?(位掩碼(__bf))))

}

SET_BITS(MCDR2,MCDR2_ADDRESS,register number);方法d:

#定義?bwMCDR2_ADDRESS?四

#定義?bsMCDR2_ADDRESS?17

#定義?bmMCDR2_ADDRESS?位掩碼(MCDR2地址)

#定義?位掩碼(__bf)

(((1U?& lt& lt?(bw?##?__bf))?-?1)

& lt& lt?(bs?##?__bf))

#定義?SET_BITS(__dst,?__bf,?__val)

((__dst)?=?((__dst)?& amp?~(位掩碼(__bf)))

|

(((__val)?& lt& lt?(bs?##?__bf))

& amp?(位掩碼(__bf))))

SET_BITS(MCDR2,MCDR2_ADDRESS,

註冊號碼);d方法是我見過最好的集合運算函數,是arm公司源代碼的壹部分。它僅用三行代碼就實現了許多功能,幾乎涵蓋了所有的位操作功能。方法C是它的變種,味道需要仔細了解。

第三招:用數學方法解題。

現在我們推導高效C語言寫作的第二招——用數學方法解決問題。數學是計算機之母。沒有數學的基礎和底子,就沒有計算機的發展。所以在編寫程序時,采用壹些數學方法,會使程序的執行效率提高幾個數量級。比如求1~100的和。

方法e:

int?我?,?j;

為了什麽?(我?=?1?;我& lt=100;?我?++)

{

j?+=?我;

}方法f

int?我;

我?=?(100?*?(1+100))?/?這個例子是我印象最深的壹個數學用例。是我的電腦啟蒙老師測試的。那時候我才小學三年級。可惜我不知道怎麽用公式N×(N+1)/ 2來解決這個問題。方法E已經循環了100次解題,也就是說至少用了100次賦值,100次判斷,200次加法(I和J);方法F僅使用1次加法、1次乘法和1次除法。效果不言而喻。所以我現在編程的時候,更多考慮的是尋找規律,發揮數學的力量,提高程序的效率。

第四招:用位運算用位運算。減少除法和模運算。在計算機程序中,數據位是可以操作的最小數據單位。理論上所有的運算和操作都可以通過“位運算”來完成。壹般的位操作是用來控制硬件或者做數據轉換的,但是靈活的位操作可以有效的提高程序運行的效率。例子如下:

方法g

int?I,J;

我?=?257?/8;

j?=?456?%?32;方法h

int?I,J;

我?=?257?& gt& gt3;

j?=?456?-?(456?& gt& gt?4?& lt& lt?4);從字面上看,H好像比G麻煩很多,但是仔細看生成的匯編代碼就會明白,G方法調用的是基本的模函數和除法函數,既有函數調用,也有很多匯編代碼和寄存器。方法H只是幾個相關的程序集,代碼更簡單高效。當然由於編譯器的不同,效率差距可能不大,但是從我目前遇到的MS C,arm C來看,效率差距還是不小的。

對於以2的指數冪為“*”、“/”或“%”因子的數學運算,轉化為移位運算”

c語言的位運算不僅提高了運算效率,而且廣泛應用於嵌入式系統的編程中。),或者(|),而不是(~)運算,這和嵌入式系統的編程特點有很大關系。我們通常需要設置硬件寄存器的位。例如,我們將AM186ER處理器的中斷屏蔽控制寄存器的最低6位設置為0(中斷2)。最常見的方式是:

#define INT_I2_MASK 0x0040

w temp = in word(INT _ MASK);

outword(INT_MASK,wTemp & amp~ INT _ I2 _ MASK);

將該位設置為1的方法是:

#define INT_I2_MASK 0x0040

w temp = in word(INT _ MASK);

outword(INT_MASK,w temp | INT _ I2 _ MASK);

判斷該位是否為1的方法是:

#define INT_I2_MASK 0x0040

w temp = in word(INT _ MASK);

if(wTemp & amp;INT_I2_MASK)

{

.../*這個位是1 */

}

使用這壹招需要註意的是CPU不同帶來的問題。比如在PC上用這種方式編寫的程序,在PC上調試,移植到16位的計算機平臺上可能會產生代碼隱患。所以這壹招只能在壹定的先進技術基礎上使用。

第五招:匯編內嵌在熟悉匯編語言的人眼裏,用C語言寫的程序都是垃圾。“這種說法雖然有點偏激,但有其道理。匯編語言是效率最高的計算機語言,但是用它寫操作系統是不可能的吧?因此,為了獲得程序的高效率,我們不得不采用靈活的方法——嵌入式匯編和混合編程。在線匯編主要用在嵌入式C程序中,也就是將_asm{}嵌入式匯編語句直接插入到C程序中。

例如,將數組1賦給數組2,並要求每個字節都匹配。

char string1[1024],string 2[1024];

方法壹

int I;

for(I = 0;我& lt1024;I++)

*(string2 + I) = *(string1 + I)

方法j

#ifdef _PC_

int I;

for(I = 0;我& lt1024;I++)

*(string 2+I)= *(string 1+I);

#否則

#ifdef _arm_

__asm

{

MOV R0,字符串1

MOV R1,字符串2

MOV R2,#0

循環:

LDMIA R0!,[R3-R11]

STMIA R1!,[R3-R11]

添加R2,R2,#8

CMP R2,#400

BNE環路

}

#endif

再舉壹個例子:

/*將兩個輸入參數的值相加,並將結果存儲在另壹個全局變量中*/

int結果;

void Add(long a,long *b)

{

_asm

{

MOV阿克斯

MOV·BX灣

添加AX,[BX]

MOV結果,AX

}

}

方法壹是最常用的方法,使用1024個循環;方法J是根據不同的平臺來區分的。在arm平臺下,用嵌入式匯編完成同樣的操作只需要128個周期。這裏有些朋友會說,為什麽不用標準的內存復制功能呢?這是因為源數據可能包含數據為0的字節,在這種情況下,標準庫函數將提前結束,不會完成我們要求的操作。該例程通常應用於LCD數據的復制過程。根據不同的CPU,巧妙地使用相應的嵌入式匯編可以大大提高程序執行的效率。

雖然是殺手鐧技能,但是輕易使用就會付出沈重的代價。這是因為嵌入式匯編的使用限制了程序的可移植性,使得程序在不同平臺上移植的過程,臥虎藏龍,險象環生!同時,這壹招也違背了現代軟件工程的思想,只有在絕對必要的情況下才能采用。

第六個技巧是使用寄存器變量。當壹個變量被頻繁讀寫時,需要反復訪問內存,從而花費大量的訪問時間。為此,C語言提供了壹個變量,即寄存器變量。該變量存儲在CPU的寄存器中。使用時,可以直接從寄存器中讀寫,無需訪問存儲器,提高了效率。寄存器變量的說明符是register。無論是循環次數多的循環控制變量,還是循環中重復使用的變量,都可以定義為寄存器變量,循環次數是應用寄存器變量的最佳候選。

(1)只有局部自動變量和形參可以定義為寄存器變量。因為寄存器變量屬於動態存儲方式,任何需要靜態存儲方式的量都不能定義為寄存器變量,包括:模塊間全局變量、模塊內全局變量和局部靜態變量;

(2) register是壹個“建議的”關鍵字,意思是程序建議把變量放在寄存器中,但最後可能因為條件不滿足,變量沒有變成寄存器變量,而是放在了內存中,但編譯器沒有報錯(C++語言中還有壹個“建議的”關鍵字:inline)。

下面是壹個使用寄存器變量的例子:

/*求1+2+3+的值...+n */

字加法(字節n)

{

寄存器I,s = 0;

for(I = 1;我& lt= n;i++)

{

s = s+I;

}

返回s;

}

這個程序循環N次,I和S是經常使用的,所以可以定義為寄存器變量。

第七招:使用硬件特性首先要了解CPU對各種內存的訪問速度,基本上是:

CPU的內部ram >;外部同步RAM >外部異步RAM >;閃存/只讀存儲器

對於已經燒錄在FLASH或者ROM中的程序代碼,我們可以讓CPU直接讀取代碼並執行,但這通常不是壹個好辦法。我們最好在系統啟動後,將FLASH或ROM中的目標代碼復制到RAM中,然後執行,以提高取指令速度。

對於UART等設備,內部有壹定容量的接收緩沖區,盡量在緩沖區滿了之後中斷CPU。例如,當計算機終端通過RS-232向目標機傳輸數據時,設置UART僅在接收到壹個字節後中斷CPU是不合適的,這樣會不必要地浪費中斷處理時間;

如果壹個設備可以通過DMA讀取,則采用DMA讀取。當讀取目標包含的存儲信息量較大,數據傳輸的基本單位是塊,傳輸的數據直接從設備發送到內存(或者反之亦然)時,DMA讀取效率更高。與中斷驅動方式相比,DMA方式減少了CPU對外設的幹預,進壹步提高了CPU與外設並行操作的程度。

我就是這樣總結出如何優化C代碼的。

  • 上一篇:世界大同的名詞解釋
  • 下一篇:如何在中國建立“以人為本”的“公共管理”新模式?
  • copyright 2024吉日网官网