2016年5月5日 星期四

ZRAM 與 Flash 置換空間的效能比較

還記得在剛到公司上班不久,就要處理產品的一個Bug。

這個問題是這樣的,從系統的日誌(Log)上看起來是因為應用程式的動態函式庫在執行期間因為無效的記憶體存取而造成Segment fault,最後從使用者這邊啟動的應用程式就發生閃退了。當時一度懷疑是 Houdini 的問題(這是經驗法則...= =),但是在開發初期到問題發生的中間 Houdini 並沒有版本更新,而且在前者程式卻沒有發生閃退。

所幸,最後是神人同事發現到開發過程中間有引進ZRAM的功能,閃退的原因是因為 ZRAM 的 alignment 問題造成程式對記憶體的超界存取。

問題解決後,資深老鳥要菜逼八本魯解釋什麼是 ZRAM....。

ZRAM是什麼?

ZRAM 是一種置換空間(Swap Space)的機制,但是相較於傳統的 Swap 是將從記憶體將分頁置換到硬碟中,ZRAM 則是將分頁置換到記憶體。但是這下又有問題了....

置換會發生不就是因為實體記憶體空間已經不夠用了,所以才要將分頁搬移到硬碟,那把分頁置換到記憶體不是在耍白痴嗎?

正是因為如此,所以要被置換出的分頁必須要經過LZOLZ4演算法壓縮,才可以置換到記憶體。

ZRAM 於 Linux Kernel 3.14版本正式合併到主線,於3.15版加入LZ4壓縮演算法。

為什麼要ZRAM?

相較於PC, 我們的手機裝置上的記憶體容量多數是比較小的,為了要讓程式有更多的記憶體空間可以使用所以我們需要置換空間。PC可以用硬碟作置換空間,那手機呢?

當然聰明的人一定會想到,用手機的 eMMC 或是 SD 卡不就行了。

但是不幸的是,eMMC 和 SD卡 因為它們的物理特性,容許寫入的次數非常少。一旦讓 eMMC 和 SD 卡承受頻繁的寫入,那麼他們很快就會壞掉了。

所以,在早期的手機(Android KitKat 以前)是沒有置換空間的。也正因為如此,我們無法在手機上使用會大量消耗記憶體的應用程式,或是只能讓記憶體中存在有限的行程。

為了解決這項問題 ZRAM 便應運而生。

ZRAM與 Disk swap 相較的優缺點

優:
1. ZRAM 置換出的存儲媒體是 RAM 且 RAM 寫入的速度遠大於 Disk 或是快閃記憶體的寫入速度
2. 可以避免快閃記憶體的磨耗

缺:
寫入 RAM 之前必須經過壓縮,不像 Disk 或快閃記憶體一樣直接寫入即可


ZRAM與 快閃記憶體 swap 效能比較

在 beaglebone black 上寫一個無限迴圈,迴圈中的每一步都會 malloc 1MB 的記憶體,
一直執行到系統的 memory killer 被叫起來為止。並用 vmstat 每秒紀錄一筆資料。

flash:

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 0  0      0 479180   1812   3136    0    0   107     4   58  112  0  6 93  1
 0  0      0 479180   1812   3156    0    0     0     0    7    8  0  0 100  0
 0  0      0 479180   1812   3156    0    0     0     0   39   54  0  1 99  0
 0  0      0 479180   1812   3156    0    0     0     0    9    8  0  0 100  0
 0  0      0 479180   1812   3156    0    0     0     0    7   10  0  0 100  0
 1  0      0 169776   1816   3688    0    0   536     0  276  133 26 71  0  3
 3  0 129228   3324     76    680   72 139600  1036 139692  913  869  5 36  0 59
 0  2 144788   2628     76    984   24 5232   188  5236  116  123  2 12  0 86
 1  1 185984   2752     76    900    0 41196     0 41196  161  162  1 35  0 64
 0  2 198552   3360     76    888    0 12568     0 12568  108  132  0  9  0 91
 0  2 198552   3496     76    888    0    0     0     0   53   61  0  2  0 98
 0  2 198552   4092     76    888    0    0     0     0   89   70  0  5  0 95
 0  3 198552   4600     76    888    0    0     0     0   83   73  0  6  0 94
 0  3 239436   4620     92    868    0 40884     4 40912  738  965  3 19  0 79
 1  2 247716   2648     96    880    0 8280     0  8288  101  113  1 17  0 82
 1  1 259520   3476     96    880    0 11800     0 11800  128  140  2 29  0 69
 3  0 262136  44508     76    412    0 2632  1148  2632  204  211  0 31  0 69


計算得到平均Swap out 速度每秒為 23830 bytes

ZRAM:

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 1  0      0 472580   2364   7732    0    0    31     4  139   46 54  2 44  0
 0  0      0 472596   2364   7736    0    0     0     0    9   12  0  0 100  0
 0  0      0 472596   2364   7736    0    0     0     0   34   48  0  0 100  0
 1  0      0 320532   2368   8268    0    0   536     0  200  132 18 41 40  2
 3  0   2184   3212     84    940  132 4020   872    12  285  197 24 76  0  0
 2  0  60992   2688     84   1208    0 57072   112     4  232  860  4 96  0  0
 2  0 119288   2820     92   1112    0 58300     0    76  256  860  4 96  0  0
 2  0 177652   2820     92   1112    0 58364     0     4  207  824  3 97  0  0
 2  0 236628   2656     92   1108    0 58972     0     0  201  803  2 98  0  0



計算得到平均Swap out 速度每秒為 47325 bytes

結論:

雖然 ZRAM 要 Swap out 會因為壓縮使用掉一些 CPU 時間,但是因為 RAM 的寫入速度比快閃記憶體要快很多。所以可以看到 ZRAM swap out 的速度整體還是比較快。