Flash晶元的通病

2021-06-27 15:27:08 字數 3520 閱讀 4127

flash晶元在寫入資料的時候有諸多效率低下的地方。包括現在常用的u盤以及ssd中的flash晶元,或者bios常用的eeprom,它們都不可避免。

1. flash晶元儲存的通病之一:erase before overwrite

對於機械磁碟來說,磁碟可以直接用磁頭將對應的區域磁化成任何訊號,如果之前儲存的資料是1,新資料還是1,則磁頭對1磁化,結果還是1;如果新資料是0,則磁頭對1磁化,結果就變成了0。而flash則不然,如果要向某個block寫入資料,則不管原來block中是1還是0,新寫入的資料是1還是0,必

須先erase整個block為全1,然後才能向block中寫入新資料。這種額外的erase操作大大增加了覆蓋寫的開銷。

更難辦的是,如果僅僅需要更改某個block中的某個page,那麼此時就需要erase整個block,然後再寫入這個page。那麼這個block中除這個page之外的其他page中的資料在erase之後豈不是都變成1了麼?是的,所以,在erase之前,需要將全部block中的資料讀入ssd的ram buffer,然後erase整個block,再將待寫入的新page中的資料在ram中覆蓋到block中對應的page,然後將整個更新後的block寫入flash晶元中。可以看到,這種機制更加大了寫開銷,

形成了大規模的寫懲罰。這也是為何ssd的快取通常很大的原因。

就像cdrw光碟一樣,如果你只需要更改其上的幾kb資料,那麼就要先複製出全盤700mb的資料,然後擦除所有700mb,然後再寫入更改了幾kb資料的700mb資料。

ssd的這種寫懲罰被稱為write amplification(寫擴大),我們依然使用寫懲罰這個詞。寫懲罰有不同的懲罰倍數,比如,需要修改乙個512kb的block中的乙個4kb的page,此時的寫懲罰倍數=512kb/4kb=128。小塊隨機寫io會產生大倍數的寫懲罰。

當ssd當向flash中的free space中寫入資料時,並沒有寫懲罰,因為free space自從上次被整盤erase後是沒有發生任何寫入動作的。這裡又牽滲到乙個比較有趣的問題,即儲存介質如何知道**是free space,**是occupied space呢?本書中多個地方論述過這一點。只有檔案系統知道儲存介質中哪些資料是沒用的,而哪些正在被檔案系統所占用,這是絕對無可置疑的,除非檔案系統通過某種途徑通告儲存介質。ssd也不例外,一塊剛被全部erase的ssd,其上所有block對於檔案系統或者ssd本身來講,都可以認為是free space。隨著資料不斷的寫入,ssd會將曾經被寫入的塊的位置記錄下來,記錄到乙份bitmap中,每一位元表示flash中的乙個block。對於檔案系統而言,刪除檔案的過程並不是向這個檔案對應的儲存介質空間內覆蓋寫入全0或者1的過程,而只是對元資料的更改,所以只會更改元資料對應的儲存介質區域,因此,刪除檔案的過程並沒有為儲存介質自身製造free space。所以說,對於ssd本身來講,free space只會越來越少,最後導致沒有free space,導致每個寫動作都產生寫懲罰,類似copy on write,而且copy和write的很有可能都是一些在檔案系統層已經被刪除的資料,做了很多無用功,寫效能急劇下降。對於一塊使用非常久的ssd來講,就算它在被掛載到檔案系統之後,其上沒有檢測到任何檔案,檔案系統層剩餘空間為100%,這種情況下,對於ssd本身來講,free space的比例很有可能卻是0,也就是說只要曾經用到過多少,那麼那個水位線就永遠被標記在那裡。思考

令所有人都無法理解的是,為何哪怕在overwrite乙個cell之前必須將對應的目標——整個block放電處理呢?其原因在於干擾。由於電路設計原因,乙個page中的多個位,也就是cell,如果有的正在充電(寫入0),有的正在放電(寫入1),那麼會產生不可忽略的干擾導致問題,正因為這個限制,所以必須取捨,要麼就對整block中的所有cell充電(寫0),要麼就對其整體放電(寫1)。最後,研發人員下定決心,就取後者吧,每次先預先將整個block擦成全1,然後再接受io,io資料中遇到為1的位,對應的cell不動作,遇到為0的位,則對應的cell進行充電。這樣,不管任何時候,對於乙個block中的所有cell來講,只有「全部在放電」或者「全部/部分在充電」這兩個狀態,不會產生干擾。

好,那麼為何非要一次擦一整個block呢?一次擦乙個page不行麼?比如如果要對某page寫入101010,那麼可以先對其全擦1,或者只對其奇數字擦1,結束後再向其偶數字充電,也就是寫0?其實這牽扯到兩個問題,乙個是管理粒度的問題,粒度越小,管理開銷就越大,表現在導線與電路開銷和能耗方面,可擦除粒度越小,需要的導線和電路就越多;第二則是效率問題,如果沒遇到乙個page寫,就預先擦除一下再寫,這樣寫懲罰絕對是2倍的關係了,ssd有種演算法可以避免寫懲罰,見下文。

但是,擦除整個block,解決了干擾問題的同時卻增加了寫懲罰,這豈不是得不償失麼?非也。由於ssd使用一種辦法來避免寫懲罰以及wear off,而這種辦法的使用,需要大粒度的erase以便節約時間和提高效率,同時不增加寫懲罰。這種辦法我們將在下文描述。

eeprom每次只擦除一byte,所以效能比flash要差。

每個block中的page必須被按照乙個方向寫入,比如每個block為128個page,共512kb,則當這個block被擦除之後,ssd控制器可以先向其中寫入前32個page(或者10個page,數量不限),一段時間之後,可以再向這個block中追加寫入剩餘的page(或者多次追加一定數量的page寫入)而不需要再次擦除這個block。ssd控制器會記錄每個block中的大段連續空餘空間。但是不能夠跳躍的追加,比如先寫入0~31這32個page,然後寫入64~127這64個page,中間空出了32個page沒有追加,控制器是不會使用這種方式寫的,page都是連續排布的。但是一般來講,控制器都是盡量一次寫滿整個block的從而可以避免很多額外開銷。

2.flash晶元儲存的通病之二:wear off

隨著fg充放電次數的增多,二氧化矽絕緣層的絕緣能力將遭到損耗,最後逐漸失去絕緣性,無法保證fg中保有足夠的電荷。此時,這個cell就被宣判為損壞,即wear off。思考

ssd是如何判斷出這個cell已經不能儲存資料的呢?在write操作中,會向cell中充電,成功後會在對應的bit line中體現出cell當前的電勢,通過檢查這個電勢表示的位是否與待寫入資料中對應的位一致來判斷,一致則判斷為完好,不一致則損壞。如果遇到寫入資料位為1的情況,那麼寫入過程中對這個cell不會有任何動作。如果這個cell已經損壞,即不能被充電或者充電量太低以至於不能感應出足夠的電勢,那麼當資料被寫入之後,依然被判斷為完好。這雖然與實際不符,但是不影響使用,一旦這個實際已經損壞的cell在下次被更改為0,就會被判斷出已損壞。

損壞的cell將拖累這個cell所在的整個page被標記為損壞,因為ssd定址和io的最小單位為page。損壞的page對應的邏輯位址將被重定向對映到其他完好的預留page,ssd將這些重定向表儲存在rom中,每次加電均被載入ram以供隨時查詢。

mlc由於器件複雜,其可擦寫的壽命比較低,小於10000次。而slc則高一些,十倍於mlc,小於100000次。這個值是很驚人的,對於某些場合下,有可能一天就可以廢掉一大堆cell/page,幾個月之內當預留page都被耗盡後,就會廢掉整個ssd。這是絕對不能接受的。

寫懲罰會大大加速wear off,因為寫懲罰做了很多無用功,增加了不必要的擦寫,這無疑使本來就很嚴峻的形勢雪上加霜。但是對於讀操作,理論上每個cell可以承受高數量級的次數而不會損耗,所以對於讀來說,無須擔心。

幾種flash儲存晶元的用途和分類

1 iic eeprom 容量小,採用的是iic通訊協議 用於在掉電時,存系統配置引數,比如螢幕亮度等。常用晶元型號有 at24c02 fm24c02 cat24c02等,其常見的封裝多為dip8,sop8,tssop8等 2 spi norflash 容量略大,採用的是spi 通訊協議 用於存放程...

產品經理的通病

7月驕陽似火,每個週末,我都會讓自己停下來,靜一靜,想一想。人生難得的是堅持。同樣,在產品的道路上,我還會繼續往下走。從技能到心智的提公升,產品經理們其實有很多路要走。也把我常犯的毛病總結一下,以便未來的道路上,能夠越走越遠。產品經理常犯的毛病 自我感覺好 很多時候大家說你厲害,肯定是拿到你身上的優...

關於AT25DF041B的flash晶元的讀寫驅動

最近公司採購了一批at25df041b的外掛程式flash晶元用來儲存資料,說讓我負責該晶元的驅動程式的編寫。但是我拿到晶元發現這晶元的 資料幾乎沒有,md,完全從頭摸索,浪費了我3天!之前一直用w25q系列的flash晶元,本以為都是spi的驅動,但是還是有一些差別的需要自己去摸索!好了,廢話不多...