Ubuntu Weekly Recipe

第8回体感速度の改善 : bootchart, concurrent boot, readahead, preloadの利用

今回は、Ubuntuの起動速度の計測・OSブート時間の短縮・デスクトップ環境のレスポンス速度を改善させる方法など、体感速度を改善させる方法を紹介します。

なお、今回の手法のうち幾つかはきわめて富豪的なものですので、十分なパフォーマンスがあるシステムで速度を稼ぐためのものです。低速なPCを利用している場合、これらのレシピを適用するとかえって体感速度が低下する可能性がありますので、無条件に適用することは避けてください。

おおむね2005年以降のPCで、かつ、メモリが1.5GB以上搭載されていれば効果があると考えられます。

富豪的アプローチを採用しているレシピには、⁠※富豪的)という目印をつけてあります。

起動速度の計測 / bootchartのインストール

一般にパフォーマンスチューニングを行う場合に、最初に行うべきはプロファイルを取得し、どこで起動に時間がかかるのかを判定することです。Ubuntuでは、OS起動時にどの処理で時間がかかっているのかを確認し、問題を改善するためにはbootchartというツールを用いるのが一般的です。

bootchartはmainリポジトリに収容されていますので、aptやSynapticからインストールします。

$ sudo apt-get update
$ sudo apt-get install bootchart

bootchartをインストールしてシステムを再起動すると、bootchartによって起動時の各プロセスの動作状況が記録され(さらに、起動時に自動的にグラフを生成し⁠⁠、/var/log/bootchart/ディレクトリに起動時に行われた処理をグラフにしたものがPNGファイルとして記録されます。

図1 /var/log/bootchart/ディレクトリをFirefoxで表示させた例
図1 /var/log/bootchart/ディレクトリをFirefoxで表示させた例

このグラフには起動時にかかった時間だけでなく、その時点でのCPU/Diskの利用率といったパラメータも記録されています。以下は筆者が利用しているPCのグラフの例です。

図2 筆者のPCのBootchartの例
図2 筆者のPCのBootchartの例

このグラフから、起動に39秒かかっていること、CPUパフォーマンスにはまだ余裕がありそうなこと、Disk utilizationがグラフの上限ぎりぎりである時間が長いこと(=CPUよりもDiskの性能が足を引っ張っていること)が見て取れます。これはこのPCがノートPCであるため、2.5inch HDDのパフォーマンスがボトルネックになっている可能性が高いためと思われます。このPCにハードウェア的な措置を行って起動時間を短縮させる場合、HDDを交換する(SSDを用いる)のが良さそうです。

また、bootchartは起動時に実行されるプロセスごとに経過時間を計測できますので、起動に異常に時間がかかるような問題が起きている場合の原因追求に利用することができます。今回の例で見ると、少なくとも異常に長い時間動作しているプロセスはありませんので、どれか特定のプロセスの処理に問題が起き、それによって起動が遅延しているわけでもなさそうです。なお、筆者の所有するPCの中ではこのマシンがもっとも起動が遅いので、Ubuntuの起動の平均時間が40秒程度だと思うのは正しくありません(EeePCはSSDの効果もあってか極端に起動が速く、30秒かからず起動します⁠⁠。

普通のユーザであれば頻繁に行うことではありませんが、PCの乗り換え時にbootchartを使えば、客観的に性能の向上を見て取ることができます。一度はbootchartを取得してみることをお勧めします。bootchartが不要になった場合、/boot/grub/menu.lstのbootオプションに"bootchart=disable"を追加すれば停止することができますが、通常はパッケージを削除した方が手軽です。

$ sudo apt-get remove bootchart

起動処理のチューニング

前述のbootchartを使うことで、起動処理のプロファイルが取れることがわかりました。それではこれを用いて、起動処理の高速化を体験してみましょう。

Ubuntuの起動処理は通常、一度に1つずつ処理が実行されるようになっていますが、これを並列に実行させてみます。このためのオプションが、/etc/init.d/rcに用意されています。以下は同ファイルの該当部の抜粋です。

# Specify method used to enable concurrent init.d scripts.
# Valid options are 'none' and 'shell'.
CONCURRENCY=none

デフォルトではCONCURRENCY変数は「none」になっていますので、これを「shell」に変更します。


# Specify method used to enable concurrent init.d scripts.
# Valid options are 'none' and 'shell'.
CONCURRENCY=shell

また、このままだとdsubとhalが競合状態に陥り、hal関連の処理が正常に終了しなくなり、無線LANデバイスなど、ハードウェア認識に問題が生じる可能性があります。この場合、ログイン後に次のようなダイアログが表示されます。

図3 halのエラーダイアログ
図3 halのエラーダイアログ

このような場合は以下を実行し、halの起動順を遅らせます。

sudo mv /etc/rc2.d/S12hal /etc/rc2.d/S13hal
sudo mv /etc/rc3.d/S12hal /etc/rc3.d/S13hal
sudo mv /etc/rc4.d/S12hal /etc/rc4.d/S13hal
sudo mv /etc/rc5.d/S12hal /etc/rc5.d/S13hal

この問題はLaunchpad bug#149881として登録されているため、将来的には不要になるはずです。

うまく設定が完了すれば、CONCURRENCY=shell設定により起動時に各initスクリプトが並列に実行され、起動時間が短縮されます(HDDアクセスなどのI/O待ちや、各種probeに関するsleep処理など、無為な待ち時間が減少します⁠⁠。例として挙げている筆者の環境の場合、39秒から36秒に低減しました。

図4 CONCURRENCY=shellをセットした場合の起動時間
図4 CONCURRENC

筆者の例では短縮できた時間が3秒程度でしたので微妙なところですが、マシンによってはこの変更で10秒近く低減できる場合もあるようです。前記のdbusのように、一部のinitスクリプト(特に起動順に注意する必要があるスクリプト)で問題が起こる場合もあるようですが、比較的簡単に起動時間を短縮できるでしょう。

なお、前回触れたEeePC用のeee-ubuntu-supportでは、この変更が自動的に実行されるようになっています。EeePCを利用している場合は手動で変更する必要はありません。

readahead, preloadの利用(※富豪的)

ここからは起動処理が終了した後、主にデスクトップ環境に入ってからの処理の高速化になります[1]⁠。

掲題のreadaheadとpreloadは、どちらもLinux Kernelのディスクキャッシュを利用することで、体感性能を向上させるためのツールです。

Linux KernelはHDDから読み込んだファイルをメモリ空間に保持するため、二度目以降のアクセスはHDDへアクセスせずに済ませることができる、という原理を利用します。この動作を簡単に体験するためには、今すぐログアウトし、再度ログインしてみてください。システムに十分なメモリが搭載されていれば、ログイン処理やアプリケーションの起動が、きわめて高速に実行されるはずです。逆に、この状況で速度が改善しなかった場合、ファイルキャッシュを保持するだけのメモリがシステムにないと考えられますから、以下の処理を行ってもほとんど意味がありません。

また、この処理は「いずれ必要になるHDDアクセスをあらかじめ行うことによって、ユーザが操作を行ったタイミングでは待ち時間を短くする」というものですので、体感時間は短くなりますが、実際の処理に必要な時間はそれほど短くならないことに注意してください。

利用方法を順に見ていきましょう。

readaheadの利用

readaheadは、前述の通り、必要になるファイルを読み込むことでディスクキャッシュにファイルを格納させ、アクセスが必要になった時点からの体感時間を短くするためのツールです。Ubuntuではデフォルトで起動するように設定されており、また、一般的なプロファイルがあらかじめインストールされています(つまり、何も設定しなくてもreadaheadの恩恵を受けています⁠⁠。

デスクトップ環境で利用するファイルは、/etc/readahead/desktopにリストされていますので、ここにFirefoxやgimp, OpenOfficeなどのアプリケーションをフルパスで記載することで、起動時間をより短縮することができるでしょう。

ただし、readaheadは手動でプロファイルを作成しなければならないこと、メモリ搭載量を意識した処理が行われないことなどから、通常のデスクトップ環境ではpreloadを用いる方が便利です。readaheadが必要なのは、LiveCD環境等、preloadが利用しにくい環境で利用すべきです。

preloadの利用

preloadはreadaheadよりも便利に利用できるツールです。

標準ではインストールされていませんので、Universeリポジトリからインストールしてください。

$ sudo apt-get update
$ sudo apt-get install preload

インストールすると自動的に起動し、起動時点から常駐するようになります("/usr/sbin/preload -s /var/lib/preload/preload.state"というプロセスが発生しているはずです⁠⁠。

以降、⁠適切な」先読み処理を自動学習するようになります。ユーザが能動的に何かを行う必要はありません。動作原理は次の通りです。

まず、preloadはその時点でロードされている各種ファイル(実行ファイルや.soなどのシェアドオブジェクト)の統計情報を取得します。これは/var/lib/preload/preload.stateに記録されます[2]⁠。

preloadはこの情報を元にし、キャッシュされるファイルが空きメモリを圧迫しすぎないように調整しながら、各種ファイルに先読みを行います。この処理は/var/log/preload.logに記録されています。なお、preload.state, preload.logともにもroot権限でのみ閲覧できますので、sudo lessなどを用いて表示させてください。

これにより、実際に必要になるファイルにのみ先読みが実行されることになります。FirefoxやOpenOfficeなどの「重い」アプリケーションを起動させた後、システムを再起動することで、十分体感できるレベルで速度が改善されているのがわかるはずです。

GNOMEのメニュー表示待ちの短縮(※富豪的)

これも体感的な速度を改善するためのレシピになります。

GNOMEのメニュー表示(デフォルトでは画面上部に表示されている、[アプリケーション]や[場所]といったメニュー)は、デフォルトでは一瞬「待ち」を入れてから表示されるようになっています。

この「待ち」をゼロにすることで、体感的な待ち時間を減少させよう、というだけのショートレシピになります。

[端末]で以下のコマンドを入力します。

$ echo gtk-menu-popup-delay = 0 >> ~/.gtkrc-2.0

この後ログアウトし、ログインしなおすと、メニュー表示がデフォルトよりも「きびきび」行われることに気づくでしょう。また、XFceのメニューについてもこの設定が反映されますので、Xubuntu環境でも同様に体感性能を改善することができます。

なお、⁠待ち」なしにメニューのデータが読み込まれますので、システムが行うべき処理内容が増加します(⁠⁠待ち」があれば表示せずに済んだメニュー項目まで表示されてしまいます⁠⁠。

十分な性能がないマシンで行うと、かえって体感性能は悪化しますので注意してください。

おすすめ記事

記事・ニュース一覧