SSD HOWTO：SLCキャッシュを上手く使う(3/4)

# はじめに
　ここ数回にわたりNANDフラッシュメモリを不揮発性記憶媒体として使用するSolid State Drive（以降SSDと記載）が備える機能のひとつとして「SLCキャッシュ」を取り上げ、SLCキャッシュを上手く使うためのノウハウをまとめています。

　[前々回](https://qiita.com/ken-yossy/items/2dcbc41acbbf78d0af9e)は容量の視点から、そして[前回](https://qiita.com/ken-yossy/items/4df126cf8ff4b035a1b3)は記録されるデータの視点からSLCキャッシュの制御方式を説明し、それぞれ上手く使用する方法をまとめました。

　今回は「SLCキャッシュからのデータ追い出しの契機」の視点でまとめます。

# まとめ

* SLCキャッシュからのデータ追い出し契機判断には、SLCキャッシュの容量による判断やSSDがアイドル状態かどうかによる判断などがある
* 容量で判断している場合、追い出し処理を始める容量を明らかにした上でその容量を意識して使うとSLCキャッシュを上手く使うことができる
* SSDがアイドル状態の時に追い出し処理をする仕組みの場合、意図的にアイドル状態になりやすくすることでアクセスしていない間に追い出し処理を実行させることができる

# 【再掲】SLCキャッシュの制御方式

　代表的な「SLCキャッシュの制御方式」を再掲します。

　SLCキャッシュの挙動を特徴づける項目には大きく4つあります。それは、容量、データ、追い出し処理の契機、そして追い出しアルゴリズム、です。

:::note warn
この記事では代表的なものを示します。ここに示した項目や方式以外にも、各メーカーおよび製品に特有の項目の存在や方式の実装が考えられます。その場合、SLCキャッシュの特性も変化します。
:::

_表：SLCキャッシュの動作を特徴づける項目と代表的な制御方式_
| 項目| 代表的な方式 | 概要 |
|-:|:-|:-|
| 容量  | 静的 | 静的に容量を確保して運用  |
|   | 動的  | データ量に応じて容量を増減  |
| 記録データ  | 何でも  | 区別なし  |
|   | 小サイズのみ  | 一定サイズ未満  |
|   | 特定データのみ | 何らかの法則で決定 |
| 追い出し契機 | 容量 | （残）容量のみで判断 |
|                   | アイドル時 | アイドル時に積極的に実施 |
| 追い出しアルゴリズム | Least Recently Used (LRU) | アクセス頻度が少ない順 |
|                     | First-In-First-Out (FIFO) | 記録された時刻が古い順 |

　この表に記載した項目のうち今回は「追い出し契機」に注目します。

# 「追い出し契機」による制御とは

　これまでに説明した通り、SLCキャッシュの容量（記録できるデータサイズ、記録に使用できるブロックの数など）には上限が設定されます。上限の設定方法は製品により異なります。また、SLCキャッシュ用記録領域の割り当て方法（オーバープロビジョニング分に留める、など）も製品により異なります。

　いずれにしても、SLCキャッシュに記録されているデータの総サイズがその上限に到達すると、SSDは「SLCキャッシュを空ける」か「SLCキャッシュはそのままにして以降のライトデータを多値記録する」かのどちらかを選択します。

　SLCキャッシュ用の記録領域をオーバープロビジョニング分から割り当てている場合でも、SLCキャッシュを満杯のままにしておくとSLCキャッシュ使用時と比較して特にライト性能が大幅に低下するため、どこかのタイミングでSLCキャッシュを空けることが多いです。

![SLCキャッシュの容量が上限に到達した時](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439683/f141d11f-ff4d-0eac-cc36-e210651a9339.png "SLCキャッシュの容量が上限に到達した時")
_図1：SLCキャッシュの容量が上限に到達した例_

　今回の記事では、この「追い出しの契機（タイミング）」について説明し、その上でこのタイミングを上手く利用してSLCキャッシュ適用時の高い性能をより良く活用する方法を説明します。
 
# 具体的な制御方法と「上手く使う」方法

　それでは具体的な追い出し契機の種類や制御方法と、各制御方法に対する「SLCキャッシュを上手く使う」方法の例を示します。

　なお実際の製品は、複数方式の併用や組み合わせにより実使用環境で効果的に運用できるよう設計されていますのでご注意ください。

## 容量による制御

### 概要
　これは「SLCキャッシュに記録されたデータのサイズが予め設定した閾値を超えた」などを契機にして追い出し処理を発動する制御方式です。簡潔でわかりやすい制御方式です。

　この制御方式を採用する場合、追い出し処理の停止判断も同じくSLCキャッシュの容量で行います。例えば、以下の図2のような制御が考えられます。

![容量でSLCキャッシュからの追い出し処理を制御する方式の例(1)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439683/aeb9df23-8350-21ee-b9fe-ab9c9da30f4d.png "容量でSLCキャッシュからの追い出し処理を制御する方式の例(1)")
_図2：容量でSLCキャッシュからの追い出し処理を制御する方式の例(1)_

　図2の制御方式では追い出し処理を発動する容量と停止する容量を比較的近いサイズに設定し、追い出し処理をこまめに停止させています。追い出し処理中はホストから見た性能が低下するため、ホストから見た性能が低下する期間をなるべく短くする方式と言えます。

　1回の追い出し処理期間（＝性能が低下する期間）と性能低下度合いは一般的に反比例します。ただこの点は各メーカーの特色があらわれるため実際の挙動は製品やメーカーにより異なります。

　図3は図2とは異なる制御方式の例です。

![slc-cache-evict-algo-by-cap-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439683/48a6a19d-be01-c964-0e78-d294d1cae4ae.png)
_図3：容量でSLCキャッシュからの追い出し処理を制御する方式の例(2)_

　この図3は追い出し処理の速度が図2と同じと仮定して描いたもので、図2とは追い出し処理を停止するSLCキャッシュ容量の閾値が異なります。図3の追い出し処理停止閾値は図2と比較してかなり小さいです。

　このため、図3と図2を比較すると図3のほうが1回の追い出し処理期間が長くなりその代わり追い出し処理を実行していない期間も長くなります。

　このように、SLCキャッシュの容量で追い出し処理を制御する方式には様々なバリエーションが考えられます。

　実際の製品では、図中の追い出し発動値や追い出し停止値を動的に変更する、追い出し処理の速度を動的に変更する、など様々な工夫も適用されます。

### 上手く使うには

　まずはSLCキャッシュの追い出し制御にSLCキャッシュの容量がどのように使われているかを明らかにする必要があります。これは、初期化直後のSSDにベンチマークのようにひたすらデータを書き込むことである程度判明します。端的に言えば、図2や図3のようなグラフを実際に作成するイメージです。

　前回の記事で説明したように、あまり大きなサイズのライトコマンドを発行するとSLCキャッシュではなく多値記憶に書き込んでしまう可能性もありますので、お試しになる場合は条件を良く確認して実行してください。また一旦追い出し処理が発動してしまうとSLCキャッシュに記録されたデータのサイズ見積もりが難しくなり、正確な把握には初期化（フォーマットではなくSanitizeなど）が必要となります。

　実験の結果図2や図3に記載した「追い出し発動値」がおおよそ判明すれば、頻繁に読み書きするデータの総サイズをこの「追い出し発動値」未満に抑える、SLCキャッシュに記録したデータのサイズが「追い出し発動値」を超えたらSSDへのデータ書き込みを控える、などの工夫により上手く活用できます（図4）。

![SLCキャッシュの容量による追い出し処理制御の活用方法例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439683/6da4e3d5-4584-b49f-e292-785f926da8ed.png "SLCキャッシュの容量による追い出し処理制御の活用方法例")
_図4：SLCキャッシュの容量による追い出し処理制御の活用方法例_

## コマンド有無による制御

　これは、ホストからReadやWriteなどのコマンドが来ていない時つまり「アイドル時」に追い出し処理を実行する制御方式です。ホストからのコマンド処理中に追い出し処理を実行するとホストからは性能が低下して見えるため、これを可能な限り避ける方式です。

　アイドルであることを判断する基準は製品やメーカーにより異なります。また、ユーザによるアクセスがなくてもOSを含むシステムが読み書きすることもあるため、意図したようにアイドル状態を作り出すことは難しいです。
 
　とはいえユーザによるアクセスがなければアイドル状態になりやすいことは間違いありませんので、人間の感覚で「少し待つ」程度でもSSDにアイドル状態を作り出しそのうちに追い出し処理を実行させられる可能性があります。

# おわりに

　この記事では、「SLCキャッシュからのデータ追い出し契機」の視点で見たSLCキャッシュの活用方法をまとめました。代表的な方法として、SLCキャッシュの容量を契機とする制御とSSDがアイドル状態であることを契機とする制御を説明しました。

　実際の製品では、上記2つ以外の方法を含め複数の判断方法の組み合わせや条件の細かい調整などによりユーザが体感する追い出し処理による性能低下ができるだけ小さくなるように工夫されています。ただそれらの詳細を知ることは難しいので個別の条件について把握しておくレベルで十分だと考えます。

　逆に、読み書きするデータの総容量をできるだけSLCキャッシュの容量より小さくする、読み書きするデータのサイズを小さくする、などの工夫のほうが重要だと言えます。

　最後となる次回は「追い出しアルゴリズム」に関する制御方式に注目します。

# ライセンス表記
<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="クリエイティブ・コモンズ・ライセンス" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br />この記事は<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">クリエイティブ・コモンズ 表示 - 継承 4.0 国際 ライセンス</a>の下に提供されています。