LubuntuでHPET(高精度イベントタイマ)を採用してみよう + HPET考察
よろしい、ならばHPETだ。
え、「おまえ、イキナリなに呪文唱えてんだ」って?
あ、ちょ、踵を返さないで下さいって・・・
HPETというのは、High Precision Event Timer の事で、高精度イベントタイマと訳されるハードウェアで実装されたタイマの事です。
LinuxでHPETと聞くと逃げ出す人もいるかもしれませんが、最近はちゃんと動くようになっているので安心してください。
HPETをLubuntuで利用するには、先ずハードウェアが対応しているかの確認が必要になります。BIOSでHPETの項目があるのであれば、先ずそれを有効化してください。
EeePC 1001HAには、該当の項目はBIOS設定には見つかりません。なので、dmesgを確認する必要があります。
dmesgはdisplay messageの略で、Unix/Linux系ユーザで且つインフラ系に関与した事がある人か自作erかなら染みあるコマンドでしょう。このコマンドでは、カーネルのメッセージバッファを確認できます。
dmesgでHPETの存在を確認する方法ですが、HPETでgrepしてください。
dmesg | grep HPET
で、ACPIがHPETをコントロールしていたら、HPETが実装(物理)されていると考えて問題ないはずです。
(HPETがACPIの支配下にあれば、このコマンドの結果に ACPI: HPET ほげほげ とかの下りが見つかるはずです。多分この調査法であってるはず……)
で、EeePC 1001HAには該当の項目があってACPI支配下にいました。
A_M_I_ OEMHPET とか書かれていたので、恐らくAMI(American Megatrends Inc. : AMI) のOEM HPETなのでしょう。実際、EeePC 1001HAにはAMI BIOSが実装されているので、ほぼ確定と言っても良いはず。
念の為、もう一つ別のアプローチでも確認しておきましょう。
cat /sys/devices/system/clocksource/clocksource0/available_clocksource
この結果にhpetが含まれていれば、 clocksourceとして利用できるはずです。
モノがあることは確認できたので、clocksourceの指定に移りましょう。
clocksourceの指定はgrub2で行います。
先ずは設定の元ネタファイルを開きましょう。
sudo leafpad /etc/default/grub
前の記事( SSD x ext4 x trimのお話 )でも書いた気もしますが、leafpadはUbuntuで言うgeditの代わりのエディタです。Lubuntuにはデフォルトでleafpadが入っています。
grub時代は /boot/grub/grub.cfg を直接弄ったものですが、grub2では update-grub2 コマンドで生成されるものなので直接弄ってはいけません。
開いたら、以下を追記します。
GRUB_CMDLINE_LINUX="clocksource=hpet"
該当項目が既にあるのであれば、書き足します。
その後、保存して update-grub2 して完了。再起動すれば反映されています。
本当に適応されているかの確認は、再起動後に再びdmesgを確認してみましょう。
Switching to clocksource hpet
なんて項目が確認できれば、hpetで動いていると確信して良いと思います。
ここからは余談です。
HPETを使用すると、I/O命令が発行されるのでオーバヘッドが生じ、マイクロ秒程度までの精度しか得られないよという話がありますが、私の経験則上ではPIT(Programmable Interval Timer)を使うよりもよっぽど精度高いからあまり気にする必要は無いかなと思っています。
TSC(Time Stamp Counter)の方が、タイムスタンプの観点から見ればHPETよりも精度が高いのではないかという話もあります。確かにその通りです。読み取り効率で言えば、どう足掻いてもTSCに軍配が上がります。書籍を読むと、x86環境であればTSCが推奨される事が殆どだと思います。
しかし、TSCはCPUの状態にかなり強く依存するアーキティクチャです。
外部発振回路からCLKピンに入力を受け、TSC registerへ状態を保持します。このレジスタはCPU毎に保持されており、マルチCPU環境であればその個数分レジスタが存在する事になります。
また、CPUがアイドル状態に入るとTSC clockは停止する可能性があり、CPUの周波数が動的変動する機能が有効になっている場合は、このレジスタのカウントアップは不正確になる可能性があります。他には、CPUが超省電力状態に陥るとこれもまたレジスタのカウントアップが不正確になる可能性があります。
最近のCPUはマルチコアで且つ各コアが独立して動的に周波数が激しく変動するモードを積んだものも少なくありません。このような場合、TSCを利用すると状態からの汚染を受ける可能性があります。
であれば、今回はノートパソコンですし省電力は無視したくないので、HPETを採用した方が都合が良いのかなという判断をしました。
因みに、HPETはI/O命令によるオーバヘッド云々という話があるので、timeコマンドでclocksourceを読み取るコストも調査してみました。
$ touch ./test_file
$ chmod 777 ./test_file
$ time ./test_file
real 0m0.003s
user 0m0.000s
sys 0m0.000s
realは、プログラムの開始~終了までの時間が表示されます。これは、userとsysの時間を含んでいます。userはユーザプロセスが消費する時間でカーネルは介在し無い部分です。sysはユーザプロセスによるタスクを解決するために必要なカーネルが消費する時間です。
この結果、中々の好成績ですね。これくらいなら、私が使う分にはHPETのI/O命令によるオーバーヘッドは無視して良さそうですかね。