1.編譯器優化介紹:
由於記憶體訪問速度遠不及cpu處理速度,為提高機器整體效能,在硬體上引入硬體快取記憶體cache,加速對記憶體的訪問。另外在現代cpu中指令的執行並不一定嚴格按照順序執行,沒有相關性的指令可以亂序執行,以充分利用cpu的指令流水線,提高執行速度。以上是硬體級別的優化。再看軟體一級的優化:一種是在編寫**時由程式設計師優化,另一種是由編譯器進行優化。編譯器優化常用的方法有:將記憶體變數快取到暫存器;調整指令順序充分利用cpu指令流水線,常見的是重新排序讀寫指令。對常規記憶體進行優化的時候,這些優化是透明的,而且效率很好。由編譯器優化或者硬體重新排序引起的問題的解決辦法是在從硬體(或者其他處理器)的角度看必須以特定順序執行的操作之間設定記憶體屏障(memory barrier),linux 提供了乙個巨集解決編譯器的執行順序問題。
void barrier(void)
這個函式通知編譯器插入乙個記憶體屏障,但對硬體無效,編譯後的**會把當前cpu暫存器中的所有修改過的數值存入記憶體,需要這些資料的時候再重新從記憶體中讀出。
2.volatile總是與優化有關,編譯器有一種技術叫做資料流分析,分析程式中的變數在**賦值、在**使用、在**失效,分析結果可以用於常量合併,常量傳播等優化,進一步可以消除一些**。但有時這些優化不是程式所需要的,這時可以用volatile關鍵字禁止做這些優化。
2.看兩個事例:
1>告訴compiler不能做任何優化
比如要往某一位址送兩指令:
int *ip =...; //裝置位址
*ip = 1; //第乙個指令
*ip = 2; //第二個指令
以上程式compiler可能做優化而成:
int *ip = ...;
*ip = 2;
結果第乙個指令丟失。如果用volatile, compiler就不允許做任何的優化,從而保證程式的原意:
volatile int *ip = ...;
*ip = 1;
*ip = 2;
即使你要compiler做優化,它也不會把兩次付值語句間化為一。它只能做其它的優化。
2>用volatile定義的變數會在程式外被改變,每次都必須從記憶體中讀取,而不能重複使用放在cache或暫存器中的備份。
例如:volatile char a;
a=0;
while(!a)
doother();
如果沒有 volatiledoother()不會被執行
3.下面是使用volatile變數的幾個場景:
1>中斷服務程式中修改的供其它程式檢測的變數需要加volatile;
例如:static int i=0;
int main(void)
}/* interrupt service routine. */
void isr_2(void)
程式的本意是希望isr_2中斷產生時,在main函式中呼叫dosomething函式,但是,由於編譯器判斷在main函式裡面沒有修改過i,因此可能只執行一次對從i到某暫存器的讀操作,然後每次if判斷都只使用這個暫存器裡面的「i副本」,導致dosomething永遠也不會被呼叫。如果將變數加上volatile修飾,則編譯器保證對此變數的讀寫操作都不會被優化(肯定執行)。此例中i也應該如此說明。
2>多工環境下各任務間共享的標誌應該加volatile
3>儲存器對映的硬體暫存器通常也要加voliate,因為每次對它的讀寫都可能有不同意義。
例如:假設要對乙個裝置進行初始化,此裝置的某乙個暫存器為0xff800000。
int *output = (unsigned int *)0xff800000;//定義乙個io埠;
int init(void)
int i;
for(i=0;i< 10;i++)
該程式的目的是用來返指標*ptr指向值的平方,但是,由於*ptr指向乙個volatile型引數,編譯器將產生類似下面的**:
int square(volatile int *ptr)
由於*ptr的值可能被意想不到地該變,因此a和b可能是不同的。結果,這段**可能返不是你所期望的平方值!正確的**如下:
long square(volatile int *ptr)
注意:頻繁地使用volatile很可能會增加**尺寸和降低效能,因此要合理的使用volatile。
再分享一下我老師大神的人工智慧教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智慧的隊伍中來!
1.編譯器優化介紹:
由於記憶體訪問速度遠不及cpu處理速度,為提高機器整體效能,在硬體上引入硬體快取記憶體cache,加速對記憶體的訪問。另外在現代cpu中指令的執行並不一定嚴格按照順序執行,沒有相關性的指令可以亂序執行,以充分利用cpu的指令流水線,提高執行速度。以上是硬體級別的優化。再看軟體一級的優化:一種是在編寫**時由程式設計師優化,另一種是由編譯器進行優化。編譯器優化常用的方法有:將記憶體變數快取到暫存器;調整指令順序充分利用cpu指令流水線,常見的是重新排序讀寫指令。對常規記憶體進行優化的時候,這些優化是透明的,而且效率很好。由編譯器優化或者硬體重新排序引起的問題的解決辦法是在從硬體(或者其他處理器)的角度看必須以特定順序執行的操作之間設定記憶體屏障(memory barrier),linux 提供了乙個巨集解決編譯器的執行順序問題。
void barrier(void)
這個函式通知編譯器插入乙個記憶體屏障,但對硬體無效,編譯後的**會把當前cpu暫存器中的所有修改過的數值存入記憶體,需要這些資料的時候再重新從記憶體中讀出。
2.volatile總是與優化有關,編譯器有一種技術叫做資料流分析,分析程式中的變數在**賦值、在**使用、在**失效,分析結果可以用於常量合併,常量傳播等優化,進一步可以消除一些**。但有時這些優化不是程式所需要的,這時可以用volatile關鍵字禁止做這些優化。
2.看兩個事例:
1>告訴compiler不能做任何優化
比如要往某一位址送兩指令:
int *ip =...; //裝置位址
*ip = 1; //第乙個指令
*ip = 2; //第二個指令
以上程式compiler可能做優化而成:
int *ip = ...;
*ip = 2;
結果第乙個指令丟失。如果用volatile, compiler就不允許做任何的優化,從而保證程式的原意:
volatile int *ip = ...;
*ip = 1;
*ip = 2;
即使你要compiler做優化,它也不會把兩次付值語句間化為一。它只能做其它的優化。
2>用volatile定義的變數會在程式外被改變,每次都必須從記憶體中讀取,而不能重複使用放在cache或暫存器中的備份。
例如:volatile char a;
a=0;
while(!a)
doother();
如果沒有 volatiledoother()不會被執行
3.下面是使用volatile變數的幾個場景:
1>中斷服務程式中修改的供其它程式檢測的變數需要加volatile;
例如:static int i=0;
int main(void)
}/* interrupt service routine. */
void isr_2(void)
程式的本意是希望isr_2中斷產生時,在main函式中呼叫dosomething函式,但是,由於編譯器判斷在main函式裡面沒有修改過i,因此可能只執行一次對從i到某暫存器的讀操作,然後每次if判斷都只使用這個暫存器裡面的「i副本」,導致dosomething永遠也不會被呼叫。如果將變數加上volatile修飾,則編譯器保證對此變數的讀寫操作都不會被優化(肯定執行)。此例中i也應該如此說明。
2>多工環境下各任務間共享的標誌應該加volatile
3>儲存器對映的硬體暫存器通常也要加voliate,因為每次對它的讀寫都可能有不同意義。
例如:假設要對乙個裝置進行初始化,此裝置的某乙個暫存器為0xff800000。
int *output = (unsigned int *)0xff800000;//定義乙個io埠;
int init(void)
int i;
for(i=0;i< 10;i++)
該程式的目的是用來返指標*ptr指向值的平方,但是,由於*ptr指向乙個volatile型引數,編譯器將產生類似下面的**:
int square(volatile int *ptr)
由於*ptr的值可能被意想不到地該變,因此a和b可能是不同的。結果,這段**可能返不是你所期望的平方值!正確的**如下:
long square(volatile int *ptr)
注意:頻繁地使用volatile很可能會增加**尺寸和降低效能,因此要合理的使用volatile。
c語言中volatile關鍵字
volatile關鍵字是一種型別修飾符,用它宣告的型別變數表示可以被某些編譯器未知的因素更改 比如 作業系統 硬體或者其它執行緒等。遇到這個關鍵字宣告的變數,編譯器對訪問該變數的 就不再進行優化,從而可以提供對特殊位址的穩定訪問。使用該關鍵字的例子如下 int volatile nvint 當要求使...
C語言中volatile關鍵字
一 前言 程式的優化 1 硬體級別上的優化 a.由於記憶體訪問速度遠不及cpu處理速度,為提高機器整體效能,在硬體上引入硬體快取記憶體cache,加速對記憶體的訪問。b.在現代cpu中指令的執行並不一定嚴格按照順序執行,沒有相關性的指令可以亂序執行,以充分利用cpu的指令流水線,提高執行速度。2 軟...
C語言中volatile關鍵字
1.編譯器優化介紹 由於記憶體訪問速度遠不及cpu處理速度,為提高機器整體效能,在硬體上引入硬體快取記憶體cache,加速對記憶體的訪問。另外在現代cpu中指令的執行並不一定嚴格按照順序執行,沒有相關性的指令可以亂序執行,以充分利用cpu的指令流水線,提高執行速度。以上是硬體級別的優化。再看軟體一級...