このページの本文へ

基礎から覚える 最新OSのアーキテクチャー 第9回

マルチコアCPUを賢く使いこなす スケジューリングの秘密

2011年12月27日 12時00分更新

文● 塩田紳二

  • この記事をはてなブックマークに追加
  • 本文印刷

マルチコアCPUでは
スケジューリングのルールも変わる

 スケジューリングに関わる重要なもうひとつの要素は、メモリー管理だ。メモリーが足りなくなると、仮想記憶を管理するメモリーマネージャーは、使われていないページをスワップアウトしてメモリーを再割り当てする(関連記事)。このときに、同じぐらい使われていないページがあったらどのプロセスを選ぶか、あるいはプロセスの管理しているメモリーのなかでどのページを選ぶかは、メモリーマネージャーの仕事となる。

 しかし、現在動いているプロセスや次に起動されそうなプロセスのメモリーをスワップしてしまうと、これらを再起動するときに時間がかかってしまう。そのためI/O待ちなど何らかの理由で、しばらくの間動かないと思われるプロセスを選択する必要がある。スケジューラーの挙動を予想しなければ、スワップしても支障のないプロセスを見つけられない。

 逆に言えば、スワップアウトされたページを持つプロセスは、しばらく動けなくなる可能性がある。また再開されたとしても、スワップインのためにファイルが読み込まれるので、結局I/O待ちと同じ状態になる。メモリーマネージャーはプロセスの実行を制御するスケジューラーの、一部の役割を担っているとも言えるわけだ。

 多くのOSでは、プロセスに「優先度」をつける。優先順位を付けることで重要なプロセスや、一定時間内に繰り返す必要があるプロセスを優先して実行させる。しかし優先度だけを見ていると、場合によっては長い間、タイムスライスが回ってこないプロセスが出てしまう可能性がある。

 優先度は重要だが、長い時間で見れば各プロセスにはある程度、公平に実行時間が配分されなければならない。優先度だけを見てタイムスライスを分けると、負荷の低いときには最も優先度の低いプロセスも実行させることができるが、負荷が高くなったときには、優先度の高いプロセスしか実行されない可能性がある。スケジューラーは、こうした長期的な視点から、優先度と実行プロセスを管理しなければならない。

 また、以前解説したように、プロセスよりも小さいスケジューリングの単位に「スレッド」がある(関連記事)。ひとつのプロセスが、複数のスレッドを実行している可能性があるわけだ。そうなると、その複数のスレッドやメインスレッド(プロセス)の実行に関して正しく考慮しないと、スレッドの処理結果をほかのスレッドが待っているような場合、待っているスレッドばかりになってしまって、処理する側が後になるような可能性もある。あるいは、スレッド側で処理が終わったのにメインスレッド側へタイムスライスが回らないので、処理の終わったスレッドを終了できないといった堂々巡りになる可能性もある。

 つまり、同一プロセス内のスレッドにはある程度の依存関係があるので、優先度などの実行再開に関する条件が同じなら、同一のプロセスに所属するスレッドを続けて実行させたほうが、処理効率は高くなる(図2)。プロセスが終了すれば占有していたリソースが解放されるし、メモリーなどにも余裕が出る可能性もあるので、さっさと終わらせた方がいいわけだ。

優先度順だけでCPUをスレッドに割り当てるよりも(右)、同一プロセスのスレッドはまとめ割り当てた方が、結果的に全体の処理がスムーズになることもある

 最近のPC用プロセッサーはマルチコアが当たり前で、マルチプロセッサーでもある。またCore iシリーズやAMD FXなどは、ハードウェア的にひとつのプロセッサーコアで同時に2スレッドを実行する「SMT」(インテルではハイパースレッディング)を装備している。この場合、同一プロセスに所属するスレッドを実行するなら、同じコアや同じプロセッサーパッケージを使うほうがキャッシュが共有できるため、高速化できる可能性がある(図3)。キャッシュミスが多発すると、その分処理性能が落ちてしまうからだ。

同一プロセス内のスレッドは、同じコア、同じプロセッサーで処理した方が効率がいい

 またCore iプロセッサーやAMD FXでは、プロセッサーパッケージごとにメモリーコントローラーがあり、そこにメモリーが接続されている「NUMA」構造となっている。そのためマルチプロセッサー環境の場合、自分に接続されているメモリー内にあるプログラムやデータを使う方が、ほかのCPUに接続されたメモリーよりも効率がいい。

 プロセッサーコアとプロセスとの結びつきを、「Affinity」(親和性、親近感)と呼ぶ。こうした理由もあって、Windows 7などマルチコアCPUに対応したWindowsでは、タスクマネージャーがプロセスごとに、実行するプロセッサーコアを固定できる。デフォルトは「すべてのプロセッサー」である。APIも用意されており、スレッドやプロセスを実行するコア(複数)を、明示的に指定できる。

Windows 7のタスクマネージャーで、プロセスを選んで右クリックすると、メニューに「関係の設定」という項目がある。ここでプロセスが使うCPUを割り当てられる

 そのほかにも、プロセスの起動もスケジューラーに関係する。なぜならプロセスが起動するということは、スケジューラーの管理下にそのプロセスが入るからだ。そのためプロセス起動の処理では、準備を終えたあとはスケジューラーに起動処理を任せてしまうこともある。逆に、プロセスの起動段階ではさまざまな準備が行なわれるので、処理負荷も高い。このときにはプロセスに割り当てるCPU時間を多くすることで、起動がスムースになる。こうしたスケジューラーの細かい調整が、体感するパフォーマンスを向上させるのに役立つわけだ。

カテゴリートップへ

この連載の記事

注目ニュース

ASCII倶楽部

プレミアムPC試用レポート

ピックアップ

ASCII.jp RSS2.0 配信中

ASCII.jpメール デジタルMac/iPodマガジン