Fedora9、ハーバードチューン「実際のチューニングは明日回し」などとして長々と引っ張りつつ、結局は、ぜんぜん違う結論に至っていたりする。オイラが使っているSSDというか、コンパクトフラッシュの性能を考察する。Linuxを動かしている都合上、Windows用のベンチマークアプリであるCrystalDiskMarkの結果を引用するのはおかしいのだが、同アプリはフラッシュメディアの性能を測る上で事実上の標準となっており、Web上から結果が入手しやすいから仕方ない。Web上にて、以下の結果を発見した。MB/sまずは、Read。DMAモードをサポートしていない。DMAのmode2までだ。このモードでの理論上の最高転送速度は16.6MB/s。よって、Readの15MB/s弱というのは、フラッシュの性能ではなく、帯域の性能による制限ということになる。MB/sは、ハードディスクにとっては「ドギモを抜く」性能である。最新の高速HDD「VelociRaptor」でも1MB/sがやっとだからだ。動く部位(ヘッド)のないフラッシュならではのスコアといえよう。このスコアは、以下のように認識するのが適切である。0.50ms秒間2000回シークでき、シークタイムは0.5msである、と。これは、平均シークタイム5ms程度が「物理的限界」であるハードディスクの、軽く10倍の性能である。最底辺のフラッシュでさえだ。恐ろしく高性能といえよう。Readが大きくモノをいう。数百メガのムービー等を外部にコピーする場合などを除けば、Read面ではそこそこ十分な性能といえよう。同様に「回数」の見地から性能を測ってみる。3.612times/s4KBの書き込みと512KBの書き込み「回数」には大差がない。量的には100倍以上の差があるのに、である。Writeの結果から、どこまでが「1回」なのかを求めてみる。2019.65KB/s露骨な結果が出た。2MBまでが1回であろう。逆に言うと、一度に2MBを書き込むのがもっとも効率がよく、4KBずつ書き込むと「秒間5ページを書き込むことができない」ということである。こいつぁキッツい制限といえよう。脱線するが、チマタでは8GBのコンパクトフラッシュに比較し、16GBのものが性能が低い、という評価が出回っているが、これは構造上、書き込み単位が倍になっているためと思われる。Writeの書き込み速度が半分になるのも道理であろう。なんにせよ、OSの動作がもっさりとしてしまう要因はココにあるワケだ。通常、処理を行う際には何にをするにもReadが伴う。デバイスがWriteにかかりっきりになっていれば、Readは遅れ、それは処理の遅延、要するにもっさりに直結するのである。前回も書いたが、Linuxを含む近年のOSではデバイスに対して書き込みを遅延する。いまこの手にデータがなければ一歩も処理を先に進めることができないReadと違い、Writeなんてのは余剰なメモリに溜め込んでおいてヒマな時にやればいいという思想である。そこで私は、前回「遅延分をジョロジョロと書き込む」改造と、ReadをWriteに優先させまくる性格を持つI/Oスケジューラであるdeadlineを組み合わせ、デバイスがWriteにかかりっきりになる状態を防ぐべく、チューニングを繰り返したのである......んが、結論から言うと、どうにもできなかった。いうのも、Read面ではそこそこ十分な性能といえる15MB/sだが、秒間2回の書き込みがあると、理論上の性能は半分に、秒間4回の書き込みがあると、理論上はゼロに、もっというと、秒間8回の書き込みがあると、2秒間の遅延が発生してしまう。上述のとおり、デバイスへの要求は「回数」の観点で制限し、帯域を保護すべきだが、オイラが改造を加えたpage-writeback.cのレイヤでは「ページ(4KB)」単位での制御しかできない。いって、最低ラインである秒間4回に配慮して、kupdate_max_writeback_pagesに2、dirty_writeback_centisecsに100を指定して毎秒書き込みを指定すると、100MBの書き込みを処理し終えるのに、2時間弱もかかってしまう。この場合、この間ずっとReadの性能は半分になるばかりか、連続書き込みが抑制されてしまうので、フラッシュの弱点である書き込み回数が爆発的に増加してしまう。このヘンが判明したあたりで、いーかげん、レスポンスの悪さに嫌気が差してきたので、8GBでx300なコンパクトフラッシュを買い「お金で解決」してしまおうかとも思ったのだが、それはそれで負けを認めるようで悔しい......そこで、新たに別の手段として、ReadデバイスとWriteデバイスを分割するという手を思いついた。問題は、チョロチョロとしたWriteでさえ、デバイスのRead帯域を大幅に圧迫してしまうため、あらゆるページインが遅延してしまうという問題である。それならば、Writeしがちな領域を別のデバイスに割り振ってしまい、結果的にWriteをゼロにしてしまえばいいのではないか?ちょっと大げさではあるが、これはハーバードアーキテクチャ化といえるだろう。事実「命令アクセスとデータアクセスを分離することで高速化できる」というのは、ハーバードアーキテクチャの利点のひとつであり、それはまさに今回の狙いそのものである。具体的には、別途装備してある16GBのSDカードに/varと/tmpを移動してしまう。SDカードは/home領域に使っているが、その用途であればOS自体の挙動に伴ってReadが発生する可能性は低い。シングルユーザモードに落ちて、/varと/tmpをSDカード側に移動する。/varと/tmpを押さえつけるのが目的ではないので、mountのbind機能を使って元の位置にぶら下げる。/etc/fstabには、以下のようなエントリを加えた。0さて、結果はというと......「いままでのもっさり感はなんだったんだッ!?」......というくらいに、飛躍的に体感レスポンスが向上した。これは悔しまぎれでも、大げさでもない。事実、速いコンパクトフラッシュを買う必要性を感じなくなってしまった。基本的な書き出しチューンは施しておく。上述の「読み書き分離」が、あまりに功を奏したので、気持ち程度であり、値は適当だ。すると、デチューンしているかもしれない。ditry(ディスクに未書き出し)ページの溜め込み割合を引き上げ、定期的な書き出しチェック頻度を下げつつ、書き出し遅延を拡大する。-pさらに、I/Oスケジューラの溜め込み数も引き上げる。これによって、連続した書き込み要求を、コマンド一発で済ませる可能性が上がるはず。/sys/block/mmcblk0/queue/nr_requestsI/Oスケジューラのタイプをdeadlineに変更する。deadlineスケジューラは、Write要求を遅延し、Read要求を優先する性格のスケジューラである。deadlineスケジューラのパラメータであるfifo_batchは、連続する要求をキューに押し込む限界数、writes_starvedは、Write要求を差し置いてRead要求を優先する限界数で、これらは増加した。front_mergesはデフォルトのままとした。/sys/block/mmcblk0/queue/iosched/writes_starved/sysには、/procにおけるsysctl.confのような設定機構はなさそうだ。再起動時に再設定されるように、/etc/rc.localに以下を書き加えておく。/sys/block/mmcblk0/queue/iosched/writes_starvedなお、起動デバイスである/dev/sdaはデフォルトのままとした。このデバイスは、ほぼ読み込み専用になっており、巧みなスケジューリングは必要としないはず。noopで起動時間を計測してみたが、ログイン画面が出るまでの時間は、どれも63±1秒。回転部を持たないフラッシュメモリにとって、Readには一切の小細工は必要なさそうである。Readは、ハードディスクの10倍。読み出し専用に使えば、書き換え寿命に対する不安も払拭である。「地雷とハサミは使いよう」といえよう。いやぁ、回り道したものの、ひさびさに有意義な試行であった。1.8.7-p374。