第1章 はじめに

時間計測はOSを構成する基礎技術です.時間計測にはタイマーと呼ばれるハードウェアが使われます.歴史的に様々なタイマーが開発されPCに搭載されてきました.本書では,2019年現在の典型的な構成のPC*1に搭載されているタイマーであるACPI PMタイマー,Local APICタイマー,およびTSCの制御方法を説明します.また,UEFIの規格で定められているRTCにも触れます.

[*1] 従来はPC/AT互換機と呼ばれていたものだが,ISAバスに代わりPCIバスが,PS/2に代わりUSBが,レガシーBIOSに代わりUEFI BIOSが使われるようになった現在,もはやPC/AT互換機と呼べる要素がなくなった.

本書の構成は次の通り.第2章でそれぞれのタイマーを紹介し,特徴を説明します.第3章でACPI PMタイマーの制御方法を詳しく説明します.ACPIテーブルの取り扱い方法も紹介します.第4章でLocal APICタイマーの制御方法と割り込みのやり方を説明します.第5章でTSCの周波数の計算方法や使い方を紹介します.第6章でUEFI BIOSを使った現在時刻の取得方法を紹介します.

1.1 周波数と時間の関係

本書を読むにあたり,周波数と時間の関係を知っておくことは役に立ちます.ここで簡単に説明します.

本書で扱うタイマーは,基本的に「周期的な信号の数を数える装置」といえます.皆さんがゲームコントローラーのボタンをずっと連打し続ける様子を考えてください.1秒間に何回押せるでしょうか.16回押せたら名人ですね.それだと疲れるので,1秒に3回のペースで連打し続けるとしましょう(図1.1).タイマーはその連打の数を数えることによって時間を計るものです.3数えたら1秒,6になれば2秒,という具合に,数え始めたときからの秒数を知ることができます.

1秒3回のペースでボタン連打する様子

図1.1: 1秒3回のペースでボタン連打する様子

周波数とは単位時間に発生する信号の数です.普通は単位時間として「1秒」を採用し,単位はHzを使います.1秒間に3連打であれば3Hzということになります.10秒間に3連打なら,1秒あたり0.3連打となり0.3Hzと書けます.

周波数が分かると経過時間を計算することができます.例えば,3Hzで連打し続けているなら,3つ数えれば1秒,6数えれば2秒,という具合です.これを数式で書くと次の通りです.

経過時間\mathrm{(秒)}=\frac{信号の数}{周波数\mathrm{(Hz)}}

周波数が大きいほど細かく時間を計れます.3Hzでは0.33秒ずつしか計れませんが,1KHzであれば1ミリ秒単位で経過時間を計ることができます.どれだけ細かく計れるかを 分解能と呼びます.3Hzのタイマーより1KHzのタイマーの方が約333倍高い分解能を持つといえます.

タイマーが数える周期的な信号は,コンピュータに搭載された クロックと呼ばれる部品が電気的に生成しています.誰かがボタンを連打しているわけではないですが,クロックが同じようなことを電気的にやっているわけです.本書で紹介するタイマーは数MHzから数GHz程度のクロックを採用しています.用途にも依りますが,コンピュータで実現したい処理の多くに対応できる程度には高い分解能です.

蛇足ですが,最後に 精度の話もしておきます.クロックは周囲の温度や電圧などに連動して周波数がわずかに変化するという特徴があります.そのため,例えば公称値が1KHzとなっているクロックでも,ある時は1秒に990回しか信号を生成しないかもしれませんし,また別のときは1010回の信号を生成するかもしれません.周波数の変動しにくさのことを精度と呼びます.990Hzから1010Hzで変動するクロックより,999Hzから1001Hzの範囲でしか変動しないクロックの方が精度が高いということになります.精度を表す指標として誤差をパーセント(%)で書くことが多いです.前者のクロックは誤差が±1%のクロック,後者は誤差が±0.1%のクロックということになります.

1.2 謝辞

この本の表紙は,縁あって絵師の三國さんに担当いただきました.テーマがタイマーということでメイドさんが各種の時計の世話をするような絵で,とお願いしたところ,素晴らしい絵を描いていただきました.メイドさんは,タイマーからの割り込みを担当する割り込みコントローラという位置付けです.手に持っているのは振り子時計のゼンマイの巻き鍵です.

三國さんは精力的に創作活動を行っています.活動ホームページはhttps://392studio.wixsite.com/abambooleafboatです.素敵な絵が置いてあるギャラリーやお仕事募集のページなどがありますので,三國さんの絵が気になった方は是非アクセスしてみてください.

第2章 タイマーの種類

現代のPCと,その前身となるPC/AT互換機には歴史的に様々なタイマーが搭載されてきました.本章では代表的なタイマーを一通り眺めます.

2.1 PIT(Intel 8254)

PC/AT互換機の時代のタイマーと言えばこれです.PITはProgrammable Interval Timerの略で,周期(interval)が設定可能(programmable)という意味があります.もともとはIntel 8254という単体のICチップが使われていましたが,今ではインターフェースの互換性を保ったままチップセットに組み込まれています.

このタイマーは割り込みを発生できるため,典型的にはマルチタスクの切り替えに使われます.一定時間毎に割り込みを発生させ,複数のタスクを順次切り替えていくのです.また,その割り込みの回数を数えることによってOSの中で時間を計ることができます.1つのPITに3チャンネルのタイマーが内臓されており,メモリのリフレッシュ用タイマーとして,またビープスピーカーの音源としても使われます.[1]ではタスク切り替え,メモリリフレッシュ,それからビープ音源のために使っています.

PITはとても古い仕様のタイマーですので,今ではレガシーデバイスと見なされます.レガシーデバイスは時代の流れとともに切り捨てられていきますから,近い将来PITが搭載されないPCが出てくると思います.もしかしたら,すでにそういう製品があるかもしれません.

2.2 RTC(Motorola MC146818)

Real Time Clockの略で,実際の日時情報を表す時計です.PITと違って電池によりバックアップされていて,PCの電源を落としても時刻情報が消えません.そのため,PCを起動したときの現在時刻を取得する情報源として使えます.タイマーというよりは時計として使うのが普通です.もともとはMotorola MC146818という単体のチップが使われていましたが,今ではPITと同じようにチップセットに組み込まれています.

RTCは時刻情報をCMOS RAMに記憶します.実は,このCMOS RAMは時刻情報を蓄えるのに必要な大きさより若干大きく設計されており,余った領域は汎用的な情報の記憶に使えます.この機能を活用して,電源を落としても消えてはいけない設定値の保持のためにRTCが使われます.

RTCもPITと同じくレガシーデバイスです.しかし,電池によりバックアップされた時計としてはPC内で唯一の部品というのもあり「現在時刻を維持・取得する機能」としてUEFI BIOSに組み込まれています.したがって,レガシーフリーな環境でもRTCの機能を使うことができます.詳しくは第6章で説明します.

2.3 HPET

High Precision Event Timerの略で,PITを代替 だいたいすることを目的に開発されたタイマーです.PITよりも時間分解能が優れており*1,より細かく時間を計ることができます.仕様では分解能が100nsより優れている,すなわち,周波数が10MHz以上であることが保証されています.PITの周波数は約1.2MHzですから,それに比べるとHPETの方が高い分解能を持ちます.

[*1] タイマーの名前に「精度(precision)」とあるが,本来なら「分解能」と言うべき特性であるので,本文ではそのように表現した.

HPETは動作周波数が機種ごとに違いますが,周波数を取得する手段が提供されているため問題ありません.また,割り込みを発生させる機能も持っており,PITの代わりとしてなかなか使いやすいタイマーに仕上がっています.

しかし,困ったことに,HPETはIntel社によってレガシーデバイスに分類されているらしいのです.NシリーズPentium/CeleronプロセッサーはCPUや周辺機器が1つのチップにまとまったSoCになっています.そのSoCの仕様書[2]によれば,iLB(Intel Legacy Block)と呼ばれるレガシーデバイスを集めた機能ブロックの中にHPETが含まれています.この事実は,Intel社がHPETをレガシーデバイスだと認識していることを示唆しています.また,このSoCが搭載されているPCを実際に調査してみたところ,ACPIのXSDTテーブルにHPETディスクリプタが存在しないことが分かりました.これではHPETを気軽に使うことはできません.

本書の目標はレガシーデバイスに頼らず時間を扱う方法を説明することですから,本書ではHPETを扱いません.

2.4 ACPI PMタイマー

ACPIとはAdvanced Configuration and Power Interfaceの略です.スリープ状態などの電源に関する制御,および周辺機器の管理をするための規格として,現代のPCの骨格を形成しています.その規格で定義されているPMタイマーはPower Managementタイマーの略で,システムがアイドル状態になっている時間を計るためのタイマーです.OSがシステム全体を低消費電力モードに移行するかどうかの判断に,アイドル状態の時間がヒントになります.

ACPI PMタイマーは想定されている使用目的に関係なく,汎用的に使用することができます.このタイマーは周波数が仕様で規定されていますから,特に調整などせずにそのまま時間計測に使えます.そこで,本書ではLocal APICタイマーの周波数を測るのにACPI PMタイマーを使うことにしました.

ACPI PMタイマーはACPIを採用する多くのPCに搭載されますが,主に小型機器で採用されるHardware-reduced ACPI[3]という規格ではこのタイマーは搭載されていない可能性があります.そのような機種では他の手段で時間を計る必要があります.本書ではそのような環境は考慮していません.

2.5 Local APICタイマー

ACPIと紛らわしいですが,APICはAdvanced Programmable Interrupt Controllerの略です.APICはPC/AT互換機の時代に使われていたPICという部品を進化させたものです.PICはマウスやキーボード,PITなどの割り込み信号を1つに集約しCPUに伝えるための部品で,[1]で割り込み制御のために使われています.

APICはPICを進化させたもので,大きくI/O APICとLocal APICに分けられます.PICはマルチコアCPUが存在しなかった時代に考案されたものであり,コアが複数ある状況は考慮されていませんでした.APICではマルチコアが初めから考慮されており,各CPUコアに内蔵されるLocal APICと,CPUの外部に1つだけ存在するI/O APICに分かれる構成になっています.Local APICタイマーは名前の通り,Local APICの機能としてのタイマーを意味します.

Local APICタイマーはCPUに内蔵されていますので,カウント値の高速な読み書きが可能です.割り込みにも対応しており,CPUコアに対して低オーバーヘッドで割り込みをかけることができます.Local APICタイマーはIntel SDM[4]で取り扱われる程度には標準的な機能ですから,本書ではこのタイマーをメインのタイマーとして使うことにしました.

2.6 TSC

Time Stamp Counterの略です.CPUの動作クロックを数える装置としてかなり以前のIntel CPUから搭載されています.当初はCPUが省電力モードになるとカウントが止まるようになっていたそうですが,現在はInvariant TSCといって,カウント周波数が省電力モードに依らず一定になる機種がほとんどです.搭載されているTSCがInvariantかどうかはCPUIDを調べると分かるようになっています.

TSCは割り込み機能がありませんから,ポーリングによって時間計測するような使い方が主です.Invariant TSCの動作周波数がMSRやCPUIDに記録されている機種では,その周波数を基準として他のタイマー,例えばLocal APICタイマーの周波数を測ることができます.

試し読みはここまでです。
この続きは、製品版でお楽しみください。