借り初めのひみつきち

仮ブログです。

ハイブリッドアーキテクチャ

第12世代 Intel プロセッサの最大の特徴は、高性能コア (Performance の P) と高効率コア (Efficient の E) によるハイブリッドアーキテクチャを採用していることです。

これは Arm で big.LITTLE と呼ばれていたものによく似ていて、 ひとつのプロセッサで高性能と省電力を両立させるのは難しいので、 高性能プロセッサと省電力プロセッサを両方同じパッケージに入れて切り替えて使おうという考え方です。

一見乱暴に見えますが、現代のプロセッサはマルチコア構成が当たり前で OS もマルチコア前提でコア間のマイグレーション機能が既に実装されているので、スケジューリングする際にどのプロセッサを優先的に割り当てるのか調整するだけで割と簡単に高性能と省電力を両立することができます。

実際にこの機能が使えるプロセッサが登場したので MYOS でも対応したいと考えていたところ、なんとか入手できたので対応してみたいと思います。

起動まで

早速電源を入れて OS のインストールされた USB を挿入して待つこと数秒、起動しませんでした。

どうもページング処理に問題があったようで、今回の件とあまり関係がないのでとりあえずサクッと修正します。

すると次は別の問題が発生しました。なぜか一部のコアが起動に失敗しているようです。

最初は P コアだけ起動して E コアは何か特別な処理をしないと起動できないのかと思いましたが、 CPU のスペックを確認するとなんと P コアの個数とも関係ないことがわかりました。

さらに色々調査したところ、単に最大コア数を制限する処理のバグでした…

今まで8コア以上のCPUを使ったことがなかったので、こんな簡単なバグに気づいてなかったようです。

というわけで、 APICID の振り方の癖が従来のCPUと少々異なる点が気になるものの、起動してコアを認識するところまでは従来の SMP と特に変わりませんでした。

P コアと E コアの識別

単純な SMP として動作すると、 P コアと E コアが特に区別することなくスケジューリングされます。

P コアと E コアを意識してスケジューリングするには、起動後にコアを識別する必要があります。

まず、 EAX = 7 で CPUID 命令を実行して EDX の Hybrid ビットを確認します。

ここが 1 になっていればハイブリッドアーキテクチャ対応 CPU なので、 EAX = 1A で CPUID 命令を実行します。

ここで得られた EAX の値で Core ベースのコア(P)か、 Atom ベースのコア(E)か区別できるので、スケジューラーの初期化時にコアを P-Core と E-Core に分類します。*1

なお、第12世代プロセッサの中には P コアのみや E コアのみの製品も存在していますが、これらの値がどういう動作になるか未検証です。

スケジューラーの調整

P コアと E コアを区別できるようになったら、システムの負荷状況によって P コアに割り当てたり E コアに割り当てたり制御できるようにします。

MYOS のスケジューラーは SMT 対応するために負荷測定して負荷によってコアの割り当てを制御する機能が実装済みなので、そこを改修します。

どのように分配するのがベストかはコアの構成やユースケースによると思うので、完璧な正解というのは難しいかもしれません。 とりあえず、負荷が少ないときは E コアを優先的に割り当てるようにしておきました。

なお、ハイブリッドアーキテクチャ対応の Intel プロセッサには Hardware Guided Scheduling や Intel Thread Director という支援機能が実装されていますが、詳しい使い方がマニュアルに書かれておらずよくわからなかったので今回は対応しません。

いかがでしたか?

自作 OS でも SMP 対応済みであればハイブリッドアーキテクチャ対応はそんなに難しくないことがわかりました。

とはいえ、最近の CPU は動的にクロックが変化するのでハイブリッドアーキテクチャを最大に活かすためには次のステップとしてクロック変更対応も視野に入れると良いと思います。

なお、今回対応したバージョンのリリース予定は未定です。 *2

*1:ハイブリッド対応 Intel プロセッサは俗に Core と Atom を統合したものであると言われていましたが、この書き方によると本当に Core ベースのコアと Atom ベースのコアが使われているようです。 P と E の区別がもう少しわかりやすい名前を使って欲しかったです。

*2:現在の MYOS は最近の Rust nightly の仕様変更の影響でビルドが通らず、とりあえず古いバージョンを指定すればビルドは通りますが、今後の新機能への追従が難しく、今回の変更の影響が大きすぎて対応するモチベーションも大幅に下がっているので、正式な対応時期を約束できない状態です。