中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站建設(shè)推廣特色新人學(xué)會seo

網(wǎng)站建設(shè)推廣特色,新人學(xué)會seo,網(wǎng)站建立連接不安全怎么解決,wordpress 全局置頂volatile限定符告知計算機,其他agent(而不是變量所在的程序)可以改變該變量的值。通常它被用于硬件地址以及在其他程序或同時運行的線程中共享數(shù)據(jù)。要求編譯器不要對其描述的對象作優(yōu)化處理,對它的讀寫都需要從內(nèi)存中訪問。 使用…

volatile限定符告知計算機,其他agent(而不是變量所在的程序)可以改變該變量的值。通常它被用于硬件地址以及在其他程序或同時運行的線程中共享數(shù)據(jù)。要求編譯器不要對其描述的對象作優(yōu)化處理,對它的讀寫都需要從內(nèi)存中訪問。

使用volatile關(guān)鍵字聲明變量,可以讓編譯器不對該變量進行優(yōu)化操作。如果在一些需要使用volatile關(guān)鍵字的地方而沒有使用它時,那么編譯器可能會優(yōu)化對該變量的訪問,并生成意外的代碼或達不到預(yù)期的功能。

目錄

1 volatile意味著什么

2 什么時候該使用volatile

3 不使用volatile可能出現(xiàn)的問題

4 強制使用特定指令來訪問內(nèi)存

?5 使用volatile和不使用volatile的匯編對比

6 總結(jié)

編譯器會優(yōu)化什么

作用

特點


1 volatile意味著什么

將變量聲明為volatile,是在告訴編譯器,該變量的值可能隨時會被其他實體(比如操作系統(tǒng)或者硬件)改變。該聲明可以保證編譯器不會優(yōu)化對該變量的使用,即使該變量未被使用或者未被更改。

2 什么時候該使用volatile

?對于可能在定義它們的作用域之外被修改的變量,使用volatile關(guān)鍵字。比如:

  • 會被多個子程序讀寫的全局變量。如果程序在某些計算中使用到了全局變量,由于需要經(jīng)常對該變量進行讀寫操作,編譯器為了加速讀寫操作,會生成代碼將該變量的值加載到寄存器中,以執(zhí)行該計算。如果相同的全局變量隨后在另一個子程序中被使用,編譯器可能會直接讀取寄存器中的現(xiàn)有值,而不是去內(nèi)存當(dāng)中加載(寄存器中的是最新的值,還沒有更新到內(nèi)存中,而該子程序的本意是使用內(nèi)存中的值),這可能導(dǎo)致計算錯誤。這種直接讀取寄存器里的值的做法,是因為優(yōu)化器認(rèn)為該變量是non-volatile的,不能從外部被修改,而這種假設(shè)對于內(nèi)存映射的外設(shè)是不正確的。?
  • 被用作定時(sleep或者timer)函數(shù)的延時變量。如果這種變量從未被使用過,編譯器可能會將整個延時函數(shù)代碼移除,除非將該變量聲明為volatile。
  • 被中斷服務(wù)子程序調(diào)用的變量。如下示例代碼中,中斷子程序async_interrupt在類中聲明定義,但是它可能被硬件異步調(diào)用。被調(diào)用后會改變一個名為buffer_full的變量,如果不把buffer_full聲明為volatile,check_stream函數(shù)可能會讀不到buffer_full被async_interrupt更改后的值,導(dǎo)致程序錯誤。
    • class myclass
      {public:int check_stream();void async_interrupt();private:bool buffer_full;  // must be declared as volatile
      };
      int myclass::check_stream()
      {int count = 0;while (!buffer_full){count++;}return count;
      }
      void myclass::async_interrupt()
      {buffer_full = !buffer_full;
      }

此外:

  • ?當(dāng)訪問一些內(nèi)存映射的外設(shè)時,必須使用volatile關(guān)鍵字聲明。就算編譯時采用 -O0(默認(rèn)不優(yōu)化),仍然不能保證每個變量都被當(dāng)作volatile。
  • volatile?并不意味著內(nèi)部線程通信或者同步(inter-thread communication or synchronization),要達到這個目的,需要使用原子性操作,而不是volatile。
  • 中斷或者信號處理器必須使用原子性或者volatile sig_atomic_t?類型的變量,但不是任意類型的volatile變量,以確保多線程執(zhí)行下的同步。
  • 在內(nèi)聯(lián)匯編代碼前,也可以使用volatile修飾。

3 不使用volatile可能出現(xiàn)的問題

如果需要使用volatile的時候而沒有使用,編譯器就會認(rèn)為該變量不會被當(dāng)前作用域外的其他實體修改。因此,編譯器可能會進行一些用戶意想不到的優(yōu)化操作,可能會導(dǎo)致:

  • 在輪詢硬件時,代碼可能會陷入循環(huán)。
  • 優(yōu)化可能會導(dǎo)致刪除實現(xiàn)故意定時延遲的代碼。

4 強制使用特定指令來訪問內(nèi)存

使用volatile關(guān)鍵字聲明變量,并不能保證使用特定的機器指令來訪問它。比如Cortex?-R7 and Cortex-R8的AXI外設(shè)端口是一個64-bit的外設(shè)寄存器。這個寄存器必須使用STM(多寄存寫入)來寫入,而不是STRD或者一對STR指令。不能保證編譯器在響應(yīng)相關(guān)變量或指針類型上的volatile修飾時選擇該寄存器所需的訪問方法。因此還可以使用volatile關(guān)鍵字來修飾內(nèi)聯(lián)匯編代碼。

__asm__ volatile("stm %1,{%Q0,%R0}" : : "r"(val), "r"(ptr));
__asm__ volatile("ldm %1,{%Q0,%R0}" : "=r"(val) : "r"(ptr));

?5 使用volatile和不使用volatile的匯編對比

有如下兩段代碼:

test1:

int buffer_full;
int read_stream(void)
{int count = 0;while (!buffer_full){count++;}return count;
}

test2:?

volatile int buffer_full;
int read_stream(void)
{int count = 0;while (!buffer_full){count++;}return count;
}

?test1和test2唯一的區(qū)別就是buffer_full變量是否被聲明為volatile。buffer_full是一個結(jié)束while循環(huán)的flag,當(dāng)buffer_full==true時,停止計數(shù),跳出循環(huán)并返回count。我們先看編譯結(jié)果,再進行分析:

使用?armclang --target=arm-arm-none-eabi -march=armv8-a -Os -S 命令對這兩段程序進行編譯:

test1:

1 read_stream:
2         movw    r0, :lower16:buffer_full
3         movt    r0, :upper16:buffer_full
4         ldr     r1, [r0]
5         mvn     r0, #0
6 .LBB0_1:
7         add     r0, r0, #1
8         cmp     r1, #0
9         beq     .LBB0_1     ; infinite loop
10         bx      lr

test2:

1 read_stream:
2         movw    r1, :lower16:buffer_full
3         mvn     r0, #0
4         movt    r1, :upper16:buffer_full
5 .LBB1_1:
6         ldr     r2, [r1]     ; buffer_full
7         add     r0, r0, #1
8         cmp     r2, #0
9         beq     .LBB1_1
10         bx      lr

?先看test1的匯編程序,第6行到第9行為while循環(huán)語句,寄存器r1里的值為buffer_full,進入.LBB0_1的循環(huán)后,通過第8行的cmp指令不斷比較r1是否為0,以此判斷是否要跳出循環(huán)。由于test1沒有使用volatile關(guān)鍵字聲明變量buffer_full,所以在.LBB0_1的循環(huán)內(nèi)一直讀取的是寄存器r1的值,如果在輪詢的過程中,有其他子程序改變了buffer_full的值,test1也不會跳出循環(huán),因為它并不知道buffer_full已經(jīng)被更新了。

而在test2程序中,寄存器r1中存儲的是buffer_full的地址,r2中存儲的是它的值。由于使用了volatile聲明,編譯器認(rèn)為該變量是易變的,有被其他子程序更改的風(fēng)險,所有在第5行到第9行的循環(huán)中,每次讀取buffer_full的值都是使用?ldr r2, [r1]?,直接加載內(nèi)存當(dāng)中的值,而不是如test1中的,讀取寄存器的值。所以當(dāng)外部程序更改了buffer_full的值,test2就能立馬讀取到真實的buffer_full,從而跳出循環(huán)。

6 總結(jié)

智能的(進行優(yōu)化的)編譯器可能會把變量的值臨時儲存在寄存器上,便于下次讀取,以節(jié)約時間,這個過程被稱為高速緩存。但是有一些agent在內(nèi)存上改變了變量的值,寄存器上的還是舊數(shù)據(jù),這樣就出錯了。如果被volatile 關(guān)鍵字修飾,編譯器不會進行高速緩存,直接去內(nèi)存中讀取該變量的數(shù)據(jù)。


編譯器會優(yōu)化什么

  • 將內(nèi)存變量緩存到寄存器中。
  • 調(diào)整指令順序,充分利用CPU指令流水線,進行指令重新排序讀寫指令。

作用


告訴編譯器該變量值是不穩(wěn)定的,可能被更改,需要去內(nèi)存中讀取該值而不是讀取寄存器中的備份

  • 多個線程都要用到的某個變量,而且變量的值會被改變
  • 中斷服務(wù)子程序中訪問到的非自動變量
  • 并行設(shè)備硬件寄存器的變量(如狀態(tài)寄存器)


特點

  • 易變的
  • 不可優(yōu)化,告訴編譯器不要對volatile聲明的變量進行各種優(yōu)化保證程序員寫在代碼中的指令一定會被執(zhí)行
  • volatile int a;a = 1; 如果未聲明為volatile兩條代碼會合并成一條。
  • 順序執(zhí)行的(原子性):保證volatile變量間的順序性,不會被編譯器進行亂序優(yōu)化
  • 能否和const一起用:可以,const是只讀,volatile是去內(nèi)存中讀取
  • 指針可以是volatile
  • 可以修飾函數(shù)參數(shù)
    ?

參考文章:

Effect of the volatile keyword on compiler optimizationhttps://developer.arm.com/documentation/100748/0620/Writing-Optimized-Code/Effect-of-the-volatile-keyword-on-compiler-optimization?lang=en#a48-effect-of-the-volatile-keyword-on-compiler-optimization__c-code-for-nonvolatile-and-volatile-buffer-loops

http://m.risenshineclean.com/news/65705.html

相關(guān)文章:

  • 在線作圖軟件寧波seo外包代運營
  • 廣州網(wǎng)站備案企業(yè)網(wǎng)站seo推廣方案
  • 企業(yè)品牌網(wǎng)站建設(shè)費用小姐關(guān)鍵詞代發(fā)排名
  • 深圳做網(wǎng)站推廣的公司哪家好長沙網(wǎng)站seo推廣公司
  • 動態(tài)手機網(wǎng)站怎么做seo是什么的簡稱
  • 做網(wǎng)頁專題 應(yīng)該關(guān)注哪些網(wǎng)站360收錄提交入口網(wǎng)址
  • 優(yōu)秀設(shè)計師網(wǎng)站公司企業(yè)網(wǎng)站建設(shè)
  • 上海做網(wǎng)站哪家好山東濟南最新事件
  • 網(wǎng)站文章優(yōu)化事項百度競價開戶流程
  • 張家口遠(yuǎn)大建設(shè)集團網(wǎng)站怎么創(chuàng)建網(wǎng)站的快捷方式
  • 石家莊便宜做網(wǎng)站關(guān)鍵詞搜索方法
  • 網(wǎng)站后臺密碼忘記色盲測試圖第五版
  • 河南鄭州網(wǎng)站建設(shè)百度關(guān)鍵詞挖掘查排名工具
  • 網(wǎng)站開發(fā)的目的 實習(xí)報告百度云搜索引擎入口盤搜搜
  • 企業(yè)信息港網(wǎng)站建沒怎樣自己開發(fā)一款軟件
  • 網(wǎng)站技術(shù)規(guī)劃微信管理
  • 國外網(wǎng)站開發(fā)技術(shù)現(xiàn)狀高平網(wǎng)站優(yōu)化公司
  • 寧波建網(wǎng)站公司店鋪在百度免費定位
  • 杭州企業(yè)網(wǎng)站優(yōu)化短視頻營銷常用平臺有
  • 魔法網(wǎng)站小程序開發(fā)放單平臺大全app
  • 做外匯需要關(guān)注哪幾個網(wǎng)站企業(yè)產(chǎn)品推廣運營公司
  • 怎么查詢一個網(wǎng)站有沒有做競價谷歌外鏈代發(fā)
  • 網(wǎng)站建設(shè)新聞中心百度快照客服電話
  • 天津行業(yè)建站長春網(wǎng)站優(yōu)化流程
  • 網(wǎng)站編輯工具軟文廣告投放平臺
  • 怎么做視頻解析的網(wǎng)站如何設(shè)置友情鏈接
  • 抄襲網(wǎng)站案例seo查詢友情鏈接
  • 深圳有名的做公司網(wǎng)站廣州私人做網(wǎng)站
  • 紅杭州網(wǎng)站建設(shè)推銷廣告
  • 開發(fā)網(wǎng)站開發(fā)工程師附近的教育培訓(xùn)機構(gòu)有哪些