discardというのは, ブロックデバイスのある指定領域を「もう使いません」とブロックデバイスに教えてあげる処理です. SSDでは内部でGCが走りますから, 使わない領域を教えてあげると有利になります.
今の実装は, backing deviceにそのまま転送します.
|
|
でもこれが間違ってるという物言いがつきました.
おれがドラクエをしている間に「ライトブースト, discardどうなってんだろ」と調査してアドバイスもくれるなんて, 本当にありがたいです. どこの人かは知りませんが, 回答してる時間が日本の深夜なので, たぶん海外の人だと思います.
さて, 言ってることは,
- TRIMには3つの種類がある
- 現在のライトブーストの実装は, deterministic TRIMを満たせない
- 現在存在するSSDは大抵, deterministic TRIMをサポートしているため, サポートするならそうした方がいい
私ももちろんこの分類にしては調査していましたが, 別にundeterministicでいいじゃん?と思ったので, 上のようにbackingに投げて終わりにしていました.
ライトブーストが取りうる戦略としては,
- そもそもENOTSUPPにする. SSDとHDDをミックスしてるのだから, 上位にとってはHDD相当でもいいはずだ(HDDの仲のキャッシュがでかくなったと考える).
- thepaxが言ってるように, discardをzero埋めwriteに変換する.
のどちらかだと考えています. 後者だと, RZAT (Read Zero After TRIM)も満たすことが出来ます.
ポイントは,
- キャッシュはパーシャルヒットする可能性がある
- ダーティなキャッシュはライトバックされる
1は, 例えば512Bの領域だけdiscardしますと言った場合や, 4KB discardするんだけどキャッシュ上には512Bしかないとか, そういうややこしい場合に実装が複雑になることを意味しています. 複雑になるだけでなく, おそらく, 2.2.0で獲得した「ライトバックはバックグラウンドに限るようにする」という最高の性質を破棄することになると思います.
2は, 仮にキャッシュブロックをdiscardしたとして, それがライトバックされて, キャッシュがローテートしたあとにリードした場合, データはbackingから読むことになるのですが, この時, discardしたという情報はどこに言ったのでしょうか?そもそもdeterministicと言ってるのに値が変化する可能性があるということです.
従って,
- 今のように中途半端にnon-deterministic TRIMをackしちゃうよりは, ENOTSUPPにした方が潔くてよい
- ライトバックによってdiscardの情報が残り続ける実装として, zero埋めwriteに変換するという戦略しかない
という結論になります.
ロジックとしてシンプルなのは1で, thepaxもデフォルトはこれがいいと言ってますが, 2について考えます. この実装は, discardが超多い場合や, あるかどうか知りませんが, ファイルシステムなど上位のプログラムが初期化時に全域をdiscardする場合などに破綻します. ライトブーストは, 巨大なHDDに小さなSSDを載せます. 従って, 巨大なHDDに準じた書き込み量がSSDに流れ込むと, もちろんライトバックが追いつかずにライトがサチって大変な時間がかかるというのもそうですが, 何よりSSDの寿命が危険です.
なので, 今私が一番有力だと思ってるのは1です.