C 中volatile及編譯器優化

2021-07-15 06:02:19 字數 2022 閱讀 4436

首先看一下單詞「volatile」的釋義:

volatile [ˈvɑlətl]

adj.易變的,不穩定的;(液體或油)易揮發的; **性的; 快活的,輕快的;

下邊是「c++ primer」對volatile講解的部分摘錄:

「當乙個物件的值可能會在編譯器的控制或監測之外被改變時,該物件應該宣告為volatile。因此,編譯器執行的某些例行優化行為不能應用在已經指定為volatile的物件上……

volatile修飾符的主要目的是提示編譯器,該物件的值可能在編譯器未監測到的情況下被改變。因此編譯器不能武斷地對引用這些物件的**作優化處理。」

可見,修飾符volatile定義了乙個「易變的、不穩定的、隨時可能改變的」變數,對於被宣告為volatile的變數的使用上跟普通的變數沒有什麼區別,最大的影響,就是編譯器不能按照常規方式對其進行優化。

這就引入了兩個問題:

編譯器為何對訪問變數的方式做優化以及如何優化?

首先有這麼個前提明確一下:編譯器對變數的訪問速度,暫存器快於記憶體,最慢是硬碟。

暫存器快於記憶體的主要原因體現在兩者工作方式的差別上:

暫存器本身位於cpu內部,使用起來非常簡單:第一,找到相關的位,第二,讀取這些位,over。

相比之下,記憶體的工作方式就複雜很多:

1.找到資料的指標(指標可能存放在暫存器內,所以這一步就已經包括暫存器的全部工作了。)

2.將指標送往記憶體管理單元(mmu),由mmu將虛擬的記憶體位址翻譯成實際的實體地址。

3.將實體地址送往記憶體控制器(memory controller),由記憶體控制器找出該位址在哪一根記憶體插槽(bank)上。

4.確定資料在哪乙個記憶體塊(chunk)上,從該塊讀取資料。

5.資料先送回記憶體控制器,再送回cpu,然後開始使用。

相對複雜的工作流程產生了更多的時延,累計起來就比暫存器慢很多,為了提高執行效率,編譯器會對有必要優化的變數做訪問方式上的處理,這就是編譯器對變數的優化。

多數情況下,變數是存放在記憶體而非暫存器中的,這樣對變數的訪問效率很低。對於頻繁使用的變數,編譯器自動地把變數mov到暫存器裡,使用的時候直接訪問暫存器裡的值,以加快訪問速度,這就是暫存器對變數的優化。

早期c編譯程式時不會把變數儲存在暫存器中,除非顯示使用關鍵字register修飾變數:

register long int value=123456789;

該關鍵字提醒編譯器,所定義的變數會在程式中頻繁被使用,建議編譯器將其儲存在cpu的暫存器中,以加快訪問速度。其後隨著編譯技術的進步,編譯器比程式設計師能更好的決定變數是應該儲存在記憶體還是暫存器中,早在c++ 98/03標準中就明確,用register關鍵字宣告的變數和不使用該關鍵字宣告的變數一樣,都具有自動儲存期,現在在標準c++中,雖然還可以使用該關鍵字,但已經不再影響變數的實際定義。

對於被volatile 關鍵字修飾的變數,已經提前告知編譯器該變數可能被某些編譯器未知的因素更改,比如:作業系統、硬體或者其它執行緒等。遇到這個關鍵字宣告的變數,編譯器對訪問該變數的**就不再進行優化,從而可以提供對特殊位址的穩定訪問,也就是說系統總是從它所在的記憶體位址讀取資料,而非暫存器,並且使用完成之後立即按原路儲存該變數的更改到記憶體。

volatile的用法跟關鍵字const用法一樣

volatile long clock_register;
被volatile修飾的變數表示該變數會在意想不到的情況下改變,而const修飾的變數表示變數是不可改變的,那麼乙個變數能否同時使用volatile和const修飾呢?

volatile const long clock_register;
const volatile long clock-register;
答案是肯定的,乙個例子是唯讀的狀態暫存器,用volatile修飾表示它可能會被意想不到的情況改變,這裡是指編譯器外部的情況,用const修飾表示在程式內部,不應該試圖去人為修改它的值。

C語言規範及編譯器

一 規範 c 的第乙個標準是由ansi發布的。雖然這份文件後來被國際標準化組織 iso 採納並且iso發布的修訂版也被ansi採納了,但名稱ansi c 而不是 iso c 仍被廣泛使用。一些軟體開發者使用iso c,還有一些使用 standard c。c89 1983年,美國國家標準協會 ansi...

c 編譯器編譯過程

編譯過程 編譯過程分為四步 預處理 編譯 彙編 連線 1.預處理 預處理主要處理原始檔中的 include define 等預處理等命令 預處理主要完成的工作有 參考 程式設計師的自我修養 1 刪除 define,展開巨集 2 處理條件編譯指令。預處理程式先判斷條件,再根據條件修改源 3 刪除注釋 ...

C 編譯器大全

dev c 優點 功能簡潔 noip官方編譯器 缺點 功能並不完善 不適合商業開發 面向人群 c 初學者 dev c 現在已經更名為smart c 但noip不使用該編譯器 visual c 或visual mingw 優點 1.與windows緊密結合 2.強大的類庫支援和類改造能力 3.擁有高效...