欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
volatile關(guān)鍵字
volatile關(guān)鍵字 volatile關(guān)鍵字
************************定義*******************************
volatile總是與優(yōu)化有關(guān),編譯器有一種技術(shù)叫做數據流分析,分析程序中的變量在哪里賦值、在哪里使用、在哪里失效,分析結果可以用于常量合并,常量傳播等優(yōu)化,進(jìn)一步可以死代碼消除。但有時(shí)這些優(yōu)化不是程序所需要的,這時(shí)可以用volatile關(guān)鍵字禁止做這些優(yōu)化,volatile的字面含義是易變的,它有下面的作用:
1 不會(huì )在兩個(gè)操作之間把volatile變量緩存在寄存器中。在多任務(wù)、中斷、甚至setjmp環(huán)境下,變量可能被其他的程序改變,編譯器 自己無(wú)法知道,volatile就是告訴編譯器這種情況。
2 不做常量合并、常量傳播等優(yōu)化,所以像下面的代碼:
volatile int i = 1;
if (i > 0) ...
if的條件不會(huì )當作無(wú)條件真。 意思i可能被其它程序所改變
3 對volatile變量的讀寫(xiě)不會(huì )被優(yōu)化掉。如果你對一個(gè)變量賦值但后面沒(méi)用到,編譯器常??梢允÷阅莻€(gè)賦值操作,然而對Memory Mapped IO的處理是不能這樣優(yōu)化的。
4、volatile變量能防止優(yōu)化,比如說(shuō)你在某個(gè)地方可能連續調用了好幾次這個(gè)函數,于是編譯器優(yōu)化后,可能就調用一次,其他幾次就采用這一次調用的返回值,而volatile修飾后,要讓每一次都進(jìn)行函數調用, 而不采用暫存值。
有人說(shuō)volatile可以保證對內存操作的原子性,這種說(shuō)法不大準確,其一,x86需要LOCK前綴才能在SMP下保證原子性,其二,RISC根本不能對內存直接運算,要保證原子性得用別的方法,如atomic_inc。
對于jiffies,它已經(jīng)聲明為volatile變量,我認為直接用jiffies++就可以了,沒(méi)必要用那種復雜的形式,因為那樣也不能保證原子性。
你可能不知道在Pentium及后續CPU中,下面兩組指令
inc jiffies
;;
mov jiffies, %eax
inc %eax
mov %eax, jiffies
作用相同,但一條指令反而不如三條指令快。
一般這個(gè)修飾符用來(lái)告知編譯器,被修飾的變量是個(gè)“易變的”變量(volatile的本意是“易變的”),防止編譯器進(jìn)行優(yōu)化。將變量加上volatile修飾,則編譯器保證對此變量的讀寫(xiě)操作都不會(huì )被優(yōu)化。從而可以提供對特殊地址的穩定訪(fǎng)問(wèn)。
1、中斷服務(wù)程序中修改的供其它程序檢測的變量需要加volatile;
2、多任務(wù)環(huán)境下各任務(wù)間共享的標志應該加volatile;
3、存儲器映射的硬件寄存器通常也要加volatile說(shuō)明,因為每次對它的讀寫(xiě)都可能由不同意義
使用該關(guān)鍵字的例子如下:
int volatile nVint;
當要求使用volatile 聲明的變量的值的時(shí)候,系統總是重新從它所在的內存讀取數據,即使它前面的指令剛剛從該處讀取過(guò)數據。而且讀取的數據立刻被保存。
例如:
volatile int i=10;
int a = i;
...
//其他代碼,并未明確告訴編譯器,對i進(jìn)行過(guò)操作
int b = i;
volatile 指出 i是隨時(shí)可能發(fā)生變化的,每次使用它的時(shí)候必須從i的地址中讀取,因而編譯器生成的匯編代碼會(huì )重新從i的地址讀取數據放在b中。而優(yōu)化做法是,由于編譯器發(fā)現兩次從i讀數據的代碼之間的代碼沒(méi)有對i進(jìn)行過(guò)操作,它會(huì )自動(dòng)把上次讀的數據放在b中。而不是重新從i里面讀。這樣以來(lái),如果i是一個(gè)寄存器變量或者表示一個(gè)端口數據就容易出錯,所以說(shuō)volatile可以保證對特殊地址的穩定訪(fǎng)問(wèn)。
************************典型問(wèn)題*******************************
關(guān)鍵字volatile有什么含意?并給出三個(gè)不同的例子。
一個(gè)定義為volatile的變量是說(shuō)這變量可能會(huì )被意想不到地改變,這樣,編譯器就不會(huì )去假設這個(gè)變量的值了。精確地說(shuō)就是,優(yōu)化器在用到這個(gè)變量時(shí)必須每次都小心地重新讀取這個(gè)變量的值,而不是使用保存在寄存器里的備份。下面是volatile變量的幾個(gè)例子:
1). 并行設備的硬件寄存器(如:狀態(tài)寄存器)
2). 一個(gè)中斷服務(wù)子程序中會(huì )訪(fǎng)問(wèn)到的非自動(dòng)變量(Non-automatic variables)
3). 多線(xiàn)程應用中被幾個(gè)任務(wù)共享的變量
回答不出這個(gè)問(wèn)題的人是不會(huì )被雇傭的。我認為這是區分C程序員和嵌入式系統程序員的最基本的問(wèn)題。嵌入式系統程序員經(jīng)常同硬件、中斷、RTOS等等打交道,所用這些都要求volatile變量。不懂得volatile內容將會(huì )帶來(lái)災難。
假設被面試者正確地回答了這是問(wèn)題(嗯,懷疑這否會(huì )是這樣),我將稍微深究一下,看一下這家伙是不是直正懂得volatile完全的重要性。
1). 一個(gè)參數既可以是const還可以是volatile嗎?解釋為什么。
2). 一個(gè)指針可以是volatile 嗎?解釋為什么。
3). 下面的函數有什么錯誤:
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
下面是答案:
1). 是的。一個(gè)例子是只讀的狀態(tài)寄存器。它是volatile因為它可能被意想不到地改變。它是const因為程序不應該試圖去修改它。
2). 是的。盡管這并不很常見(jiàn)。一個(gè)例子是當一個(gè)中服務(wù)子程序修改一個(gè)指向一個(gè)buffer的指針時(shí)。
3). 這段代碼的有個(gè)惡作劇。這段代碼的目的是用來(lái)返指針*ptr指向值的平方,但是,由于*ptr指向一個(gè)volatile型參數,編譯器將產(chǎn)生類(lèi)似下面的代碼:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
由于*ptr的值可能被意想不到地該變,因此a和b可能是不同的。結果,這段代碼可能返回不是你所期望的平方值!正確的代碼如下:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
************************補充*******************************
volatile的本意是“易變的” 由于訪(fǎng)問(wèn)寄存器的速度要快過(guò)RAM,所以編譯器一般都會(huì )作減少存取外部RAM的優(yōu)化。比如:
static int i=0; //應該為static volatile int i=0;
int main(void)
{
...
while (1)
{
if (i) dosomething();
}
}
/* Interrupt service routine. */
void ISR_2(void)
{
i=1;
}
程序的本意是希望ISR_2中斷產(chǎn)生時(shí),在main當中調用dosomething函數,但是,由于編譯器判斷在main函數里面沒(méi)有修改過(guò)i,因此可能只執行一次對從i到某寄存器的讀操作,然后每次if判斷都只使用這個(gè)寄存器里面的“i副本”,導致dosomething永遠也不會(huì )被調用。
如果將將變量加上volatile修飾,則編譯器保證對此變量的讀寫(xiě)操作都不會(huì )被優(yōu)化(肯定執行)。此例中i也應該如此說(shuō)明。
volatile表示變量的內容可能在程序未知的情況下被改變
比如,它對應的內存地址的內容被中斷函數,或者其他的進(jìn)程所改變
這種類(lèi)型的變量,程序執行的時(shí)候不會(huì )放到cache當中預取,而是每次用到的時(shí)候直接取得
比如,你在c中間寫(xiě)這樣的程序
for (int i=0; i <100000;i++);
空循環(huán),什么也不做
這個(gè)東西就會(huì )被優(yōu)化調,如果在int前面加入這個(gè)標記則不會(huì )被優(yōu)化的,因為i每次的變化不一定++也許在循環(huán)中間被別的程序所改變
在linux的source code(linux/mm/memory.c)中有這樣兩句:
volatile void do_exit(long code);
static inline volatile void oom(void)
{
printk("out of memory\n\r");
do_exit(SIGSEGV);
volatile修飾的確實(shí)是一個(gè)變量,而且是一個(gè)“容易變”的變量。在每次取這個(gè)變量值的時(shí)候,要求不是取它上次在某個(gè)時(shí)候取的臨時(shí)緩存變量(比如說(shuō)暫存在某個(gè)寄存器中),而是直接到內存中取。
volatile變量能防止優(yōu)化,比如說(shuō)你在某個(gè)地方可能連續調用了好幾次這個(gè)函數,于是編譯器優(yōu)化后,可能就調用一次,其他幾次就采用這一次調用的返回值,而volatile修飾后,要讓每一次都進(jìn)行函數調用, 而不采用暫存值。
volatile修飾不返回函數,比如函數體里面有exit或者死循環(huán)之類(lèi)的東西。這樣該函數被調用的時(shí)候不用把返回地址壓入堆棧,(當然還可能有其他),代碼得到優(yōu)化。這個(gè)是 GCC 的擴展
volatile在嵌入式里使用較多。有時(shí)硬件動(dòng)作會(huì )影響某存儲空間的內容,對這些變量,必須加volatile修飾。
編譯器的優(yōu)化可以把本來(lái)在內存中進(jìn)行訪(fǎng)問(wèn)的數據裝入(緩存)到寄存器中以提高訪(fǎng)問(wèn)效率。然而這種優(yōu)化在一些情況下可帶來(lái)問(wèn)題;此時(shí),應該用 volatile 告訴編譯器不要進(jìn)行這種優(yōu)化以避免問(wèn)題的出現。
每次操作前從內存取值
有volatie修飾的變量,每次操作時(shí)遵循下面動(dòng)作:
從內存取值 ---> 放入寄存器 ---> 操作 --->寫(xiě)回內存
沒(méi)有volatie修飾的變量,操作可能遵循(可能就是不是所有情況都如此):
從內存取值 ---> 放入寄存器 ---> 第一次操作 ---> 第二次操作(此時(shí)仍操作寄存器中的值) …… --->第N次操作 --->寫(xiě)回內存
舉個(gè)例子論述兩者關(guān)系:
int volatie i; //全局變量,在其它地方會(huì )被修改
while (i){
do_somethings();
}
如果i沒(méi)有被volatie修飾,當while循環(huán)執行時(shí),另一段程序并發(fā)的執行了i=0,這個(gè)循環(huán)仍不會(huì )退出,因為每次循環(huán)都是檢查寄存器中的值。
如果有volatie修飾,那么循環(huán)結束,因為循環(huán)每次檢查i的時(shí)候,會(huì )先從內存把i讀入寄存器,這個(gè)時(shí)候i在其它地方被賦0,則循環(huán)結束。
關(guān)于 volatile 我覺(jué)得這樣的解析最容易理解:
如果編譯器在代碼中發(fā)現對同一地址的兩次訪(fǎng)問(wèn)之間,沒(méi)有對該地址進(jìn)行寫(xiě)操作,那么編譯器將優(yōu)化為第一次尋址讀該地址時(shí)取得的值作為第二次尋址的值,而并不是再做第二次物理上的 I/O 尋址操作。volatile 關(guān)鍵字指示編譯器進(jìn)行強制 I/O 尋址,因為編譯器那樣的優(yōu)化,可能并不是我們真正期望的,譬如那個(gè)地址上連接著(zhù)一個(gè)傳感器上的寄存器,那么實(shí)際上,可能該寄存器的值是被傳感器自身不斷刷新的。因此,我們必要要求CPU每次都進(jìn)行 I/O 操作。
volatile 跟以前的 register 相反. register 告訴編譯器盡量將變量放到寄存器中使用, 而volatile 強制將更改后的值寫(xiě)回內存(無(wú)論是cache還是內存). 如果不寫(xiě)回內存, 對于一些全局共享的變量, 可能導致不一致問(wèn)題.
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
詳解C中volatile關(guān)鍵字
C語(yǔ)言中volatile關(guān)鍵字的作用
C語(yǔ)言中關(guān)鍵字volatile追根問(wèn)底
C語(yǔ)言丨深入理解volatile關(guān)鍵字
volatile的作用
Documentation/volatile-considered-harmful.txt 的中文翻譯
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久