亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

LINUX內(nèi)核之內(nèi)存屏障

系統(tǒng) 2118 0

@CopyLeft by ICANTH I Can do ANy THing that I CAN THink ~

Author WenHui WuHan University 2012-6-4

?

內(nèi)存屏障 (Memory Barriers)

一方面, CPU 由于采用指令流水線和超流水線技術(shù),可能導致CPU雖然順序取指令、但有可能會出現(xiàn)“亂序”執(zhí)行的情況,當然,對于” a++;b = f(a);c = f”等存在依賴關(guān)系的指令,CPU則會在“b= f(a)”執(zhí)行階段之前被阻塞;另一方面, 編譯器 也有可能將依賴關(guān)系很近“人為地”拉開距離以防止阻塞情況的發(fā)生,從而導致編譯器亂序,如“a++ ;c = f;b = f(a)”。

一個CPU對指令順序提供如下保證:

(1) On any given CPU, dependent memory accesses will be issued in order, with respect to itself.如Q = P; D = *Q;將保證其順序執(zhí)行

(2) Overlapping loads and stores within a particular CPU will appear to be ordered within that CPU.重疊的Load和Store操作將保證順序執(zhí)行(目標地址相同的Load、Store),如:a = *X; *X = b;

(3) It _must_not_ be assumed that independent loads and stores will be issued in the order given.

(4) It _must_ be assumed that overlapping memory accesses may be merged or discarded.如*A = X; Y = *A; => STORE *A = X; Y = LOAD *A; / or STORE *A = Y = X ;

?

由此可見,無關(guān)的內(nèi)存操作會被按隨機順序有效的得到執(zhí)行,但是在CPU與CPU交互時或CPU與IO設(shè)備交互時, 這可能會成為問題. 我們需要一些手段來干預編譯器和CPU, 使其限制指令順序。內(nèi)存屏障就是這樣的干預手段. 他們能保證處于內(nèi)存屏障兩邊的內(nèi)存操作滿足部分有序 .(譯注: 這里"部分有序"的意思是, 內(nèi)存屏障之前的操作都會先于屏障之后的操作, 但是如果幾個操作出現(xiàn)在屏障的同一邊, 則不保證它們的順序.)

(1) 寫(STORE)內(nèi)存屏障。在寫屏障之前的STORE操作將先于所有在寫屏障之后的STORE操作。

(2) 數(shù)據(jù)依賴屏障。兩條Load指令,第二條Load指令依賴于第一條Load指令的結(jié)果,則數(shù)據(jù)依賴屏障保障第二條指令的目標地址將被更新。

(3) 讀(LOAD)內(nèi)存屏障。讀屏障包含數(shù)據(jù)依賴屏障的功能, 并且保證所有出現(xiàn)在屏障之前的LOAD操作都將先于所有出現(xiàn)在屏障之后的LOAD操作被系統(tǒng)中的其他組件所感知.

(4) 通用內(nèi)存屏障. 通用內(nèi)存屏障保證所有出現(xiàn)在屏障之前的LOAD和STORE操作都將先于所有出現(xiàn)在屏障之后的LOAD和STORE操作被系統(tǒng)中的其他組件所感知.

(5) LOCK操作.它的作用相當于一個單向滲透屏障.它保證所有出現(xiàn)在LOCK之后的內(nèi)存操作都將在LOCK操作被系統(tǒng)中的其他組件所感知之后才能發(fā)生. 出現(xiàn)在LOCK之前的內(nèi)存操作可能在LOCK完成之后才發(fā)生.LOCK操作總是跟UNLOCK操作配對出現(xiàn).

(6) UNLOCK操作。它保證所有出現(xiàn)在UNLOCK之前的內(nèi)存操作都將在UNLOCK操作被系統(tǒng)中的其他組件所感知之前發(fā)生.

    
    
    ?
  
    LINUX對于x86而言,在為UP體系統(tǒng)架構(gòu)下,調(diào)用barrier()進行通用內(nèi)存屏障。在SMP體系架構(gòu)下,若為64位CPU或支持mfence、lfence、sfence指令的32位CPU,則smp_mb()、smp_rmb()、smp_smb()對應通用內(nèi)存屏障、寫屏障和讀屏障;而不支持mfence、lfence、sfence指令的32位CPU則smp_mb()、smp_rmb()、smp_smb()對應LOCK操作。源碼請參見《內(nèi)存屏障源碼分析》一節(jié)。
  
    ?
  

內(nèi)存屏障源碼分析

    /include/asm-generic/system.h:
  
    
      053
    
     #ifdef CONFIG_SMP
  
    
    
    
      054
    
     #define 
    
      smp_mb
    
    ()??????? 
    
      mb
    
    ()
  
    
    
    
      055
    
     #define 
    
      smp_rmb
    
    ()?????? 
    
      rmb
    
    ()
  
    
    
    
      056
    
     #define 
    
      smp_wmb
    
    ()?????? 
    
      wmb
    
    ()
  
    
    
    
      057
    
     #else
  
    
    
    
      058
    
     #define 
    
      smp_mb
    
    ()??????? 
    
      barrier
    
    ()
  
    
    
    
      059
    
     #define 
    
      smp_rmb
    
    ()?????? 
    
      barrier
    
    ()
  
    
    
    
      060
    
     #define 
    
      smp_wmb
    
    ()?????? 
    
      barrier
    
    ()
  
    
    
    
      061
    
     #endif
  

在x86 UP體系架構(gòu)中 ,smp_mb、smp_rmb、smp_wmb被翻譯成barrier:

    
    
    
      012
    
     #define 
    
      barrier
    
    () 
    
      __asm__
    
     __volatile__("": : :"memory")
  

__volatile告訴編譯器此條語句不進行任何優(yōu)化,"": : :"memory" 內(nèi)存單元已被修改、需要重新讀入。

?

在x86 SMP體系架構(gòu)中 ,smp_mb、smp_rmb、smp_wmb如下定義:

/arch/x86/include/asm/system.h:

    
    
    
      352
    
     /*
  
    
    
    
      353
    
    ? * Force strict CPU ordering.
  
    
    
    
      354
    
    ? * And yes, this is required on UP too when we're talking
  
    
    
    
      355
    
    ? * to devices.
  
    
    
    
      356
    
    ? */
  
    
    
    
      357
    
     #ifdef CONFIG_X86_32
  
    
    
    
      358
    
     /*
  
    
    
    
      359
    
    ? * Some non-Intel clones support out of order store. wmb() ceases to be a
  
    
    
    
      360
    
    ? * nop for these.
  
    
    
    
      361
    
    ? */
  
    
    
    
      362
    
     #define 
    
      mb
    
    () 
    
      alternative
    
    ("lock; addl $0,0(%%esp)", "mfence", 
    
      X86_FEATURE_XMM2
    
    )
  
    
    
    
      363
    
     #define 
    
      rmb
    
    () 
    
      alternative
    
    ("lock; addl $0,0(%%esp)", "lfence", 
    
      X86_FEATURE_XMM2
    
    )
  
    
    
    
      364
    
     #define 
    
      wmb
    
    () 
    
      alternative
    
    ("lock; addl $0,0(%%esp)", "sfence", 
    
      X86_FEATURE_XMM
    
    )
  
    
    
    
      365
    
     #else
  
    
    
    
      366
    
     #define 
    
      mb
    
    ()??? asm volatile("mfence":::"memory")
  
    
    
    
      367
    
     #define 
    
      rmb
    
    ()?? asm volatile("lfence":::"memory")
  
    
    
    
      368
    
     #define 
    
      wmb
    
    ()?? asm volatile("sfence" ::: "memory")
  
    
    
    
      369
    
     #endif
  

362~364行針對x86的32位CPU,366~368行針對x86的64位CPU。

?

    在x86的64位CPU中,mb()宏實際為:
  
    asm volatile("sfence" ::: "memory")。
  
    volatile告訴編譯器嚴禁在此處匯編語句與其它語句重組優(yōu)化,memory強制編譯器假設(shè)RAM所有內(nèi)存單元均被匯編指令修改,"sfence" ::: 表示在此插入一條串行化匯編指令sfence。
  
    mfence:串行化發(fā)生在mfence指令之前的讀寫操作
  
    lfence:串行化發(fā)生在mfence指令之前的讀操作、但不影響寫操作
  
    sfence:串行化發(fā)生在mfence指令之前的寫操作、但不影響讀操作
  
    ?
  
    在x86的32位CPU中,mb()宏實際為:
  

mb () alternative ("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2 )

由于x86的32位CPU有可能不提供mfence、lfence、sfence三條匯編指令的支持,故在不支持mfence的指令中使用:"lock; addl $0,0(%%esp)", "mfence"。lock表示將“addl $0,0(%%esp)”語句作為內(nèi)存屏障。

    關(guān)于lock的實現(xiàn):cpu上有一根pin #HLOCK連到北橋,lock前綴會在執(zhí)行這條指令前先去拉這根pin,持續(xù)到這個指令結(jié)束時放開#HLOCK pin,在這期間,北橋會屏蔽掉一切外設(shè)以及AGP的內(nèi)存操作。也就保證了這條指令的atomic。
  
    ?
  

參考資料

《memroy-barries.txt》, /Documentation/memory-barriers.txt

《LINUX內(nèi)核內(nèi)存屏障》, http://blog.csdn.net/ljl1603/article/details/6793982

LINUX內(nèi)核之內(nèi)存屏障


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久久网久久久久合久久久久 | 中文在线1区二区六区 | 天天好逼365| 国产精品分类视频分类一区 | 国产高清一级视频在线观看 | 2017天天干天天射 | 91福利视频网站 | 国产视频一 | 日本韩国欧美在线 | 久久精品国产6699国产精 | 成人性色大片 | 国产综合另类小说色区色噜噜 | 看大片全色黄大色黄 | 四虎网址在线 | 天天干天天曰天天操 | 成人激情开心网 | 国产在线2021 | 午夜一区 | 91国内精品视频 | 四虎最新免费观看网址 | 国产成人在线播放视频 | 色综合网亚洲精品久久 | 午夜伦y4480影院中文字幕 | 国产欧美在线播放 | 国产99视频精品免视看7 | 天天草天天| 波多野结衣一区二区 三区 波多野结衣一区二区三区 波多野结衣一区二区三区高清在线 | 九九九九在线精品免费视频 | 亚洲h片| 国产精品嫩草影院99av视频 | 欧美成人一区二区 | 天天干夜夜怕 | 久久久99精品久久久久久 | 波多野结衣久久精品 | 看免费一级毛片 | 特黄特a级特别特级特毛片 特黄特黄aaaa级毛片免费看 | 九九爱精品视频 | 天天爱夜夜做 | 中国美女牲交一级毛片 | 涩涩99| 99久久精品久久久久久婷婷 |