C++编译器优化
1、volatile:
易變性:volatile告訴編譯器,某個變量是易變的,當編譯器遇到這個變量的時候,只能從變量的內存地址中讀取這個變量,不可以從緩存、寄存器、或者其它 任何地方讀取。 順序性:兩個包含volatile變量的指令,編譯后不可以亂序。注意是編譯后不亂序,但是在執行的過程中還是可能會亂序的,這點需要由其它機制來保證,例如memory- barriers。 不可優化性:volatile告訴編譯器,不要對這個變量進行各種激進的優化,甚至將變量直接消除,保證代碼中的指令一定會被執行。2、NRV(Named Return Value)優化:
函數返回一個類,例如下:
class X;
X bar()
{
}
編譯器實現:
// 函數實現
void bar(X& __result) // 加上一個額外參數
{
}
// 函數調用
X x2; // 這里只是預留內存,并未調用初始化函數
bar(x2);
NRV優化后:
void bar(X& __result)
{
}
3、循環內變量優化:
void test2(char *s);
void test()
{
int i;
for (i = 0; i < 10; i ++) {
}
}
匯編代碼:
movl $10, %ebx
subl $272, %esp #分配272字節棧空間
leal -264(%ebp), %esi #取buf地址
.L2:
movl %esi, (%esp) #buf地址入棧
call test2 #調用test2
subl $1, %ebx
jne .L2 #循環未結束則跳到L2
該函數中,buf不會每次循環都生成,而是循環外生成,循環內不斷的使用。
4、算數式優化
a*2被編譯成a+a;無符號數a/2被編譯成a>>1;有符號數a/2。
5、memset函數優化
memset函數常用來初始化大段內存,但對小數據來說memset能否保持足夠高效呢?
看這段程序:
編譯成匯編:
movl $0, -24(%ebp) #設置s1
movl $0, -20(%ebp)
movl $0, -16(%ebp)
movl $0, -12(%ebp)
call test2 #調用test2
leal -8216(%ebp), %edx #設置s2
xorl %eax, %eax
movl %edx, %edi
movl $2048, %ecx
rep stosl
movl %edx, (%esp) #調用test2
call test2
movl %ebx, (%esp) #設置s3
movl $8193, 8(%esp)
movl $0, 4(%esp)
call memset
movl %ebx, (%esp) #調用test2
call test2
當數據長度比較小時(如s1是16字節),memset被編譯成連續的賦值語句;當數據長度不大于8KB時(如s2),memset用串操作指令來實現;當數據長度大于8KB時(如s3),memset被編譯成函數調用。
串操作類指令:在內存一個存儲區域連續存放著若干個字節(或字)數據,這樣一組數據稱為“數據串”(高級語言視為數組)。若每個數據是一個字節,稱“字節串”;若是字,則稱“字串”。串操作指令可以用來實現內存區域的數據串操作。串操作指令每次只處理數據串中的一個數據,但與重復前綴配合使用(重復前綴+串操作指令),則可使操作重復進行(其執行過程相當于一個循環程序的運行,重復次數由寄存器CX決定)。
總結
- 上一篇: 设计模式在vue中的应用(五)
- 下一篇: s3c2440移植MQTT