GNOMEのパフォーマンスを改善する取り組み
「Ubuntu」のデスクトップ環境は「Ubuntu 17.10」の時に、「Unity」から「GNOME」へと変更されました。「Canonical(Ubuntu開発チーム)」はアップストリームと連携し、積極的に「GNOME」の改善及び改良に取り組んできました。
「GNOME Shell」のパフォーマンス改善に対する取り組みはその一例です。
その成果により「Ubuntu 19.10」の「GNOME Shell 3.34」は、デスクトップパフォーマンスが大きく改善されています。
以下で今までの取り組み内容が紹介されています。
技術的な詳細は上記リンク先を参照してください。
GNOME Shell
「GNOME Shell」はデスクトップ環境であり、C言語及びJavaScriptで実装されています。「GNOME Shell」は「Mutter」コンポジター及びウィンドウマネージャー上で動作するソフトウェアです。
Mutter
主要な実装の大部分は「Mutter」プロジェクト内で行われており、このプロジェクトには「Clutter」や「Coglグラフィックツールキット」も含まれています。「Mutter」は1386のC言語のソースコードファイルで構成されています。
「Mutter」は「GNOME Shell」からライブラリーとして利用されることが大半ですが、もし必要なものがマウスポインターと壁紙のみであれば、「mutter」コマンドを実行し「Mutter」をスタンドアローンコンポジターとして実行することも可能です。
GNOME Shell
「GNOME Shell」プロジェクトは「Mutter」プロジェクトよりも小規模なプロジェクトであり、デスクトップパネルやランチャーなどデスクトップを構成するソフトウェアを開発するプロジェクトです。「GNOME Shell」は「Compiz」上で動作する「Unity 7」と似たような位置づけのソフトウェアです。
「GNOME Shell」は、199のC言語のソースコードファイルと157のJavaScriptのソースコードファイルで構成されています。
GNOME ShellとMutter
ここで大切なことは、「GNOME Shell」を実現するソースコードの大部分は「Mutter」プロジェクト内に存在しており、「GNOME Shell」には存在していないということです。「Mutter」プロジェクトを踏まえると「GNOME Shell」全体のおよそ10%がJavaScriptで記述され、残りの約90%がC言語で記述されています。
GNOME Shell 3.32のパフォーマンスが思わしくない
「Ubuntu 19.04」では「GNOME Shell 3.32」を採用していましたが、「GNOME Shell 3.32」は「Unity」や他のデスクトップと比較すると、遅く感じられました。遅い、重い
もし性能の低いPC上で「GNOME Shell 3.32」を動かしているなら、「GNOME Shell 3.32」はスムーズに動作しないでしょう。例え性能の高いPC上で「GNOME Shell 3.32」を動かしていたとしても、完璧なスムーズさで動作しない可能性すらあります。
JavaScriptのせいなのか?
多くのユーザーは「GNOME Shell」に「JavaScript」が含まれていること、そして「JavaScript」はインタープリター言語であることを知っています。そのため「JavaScript」のせいで遅いと考えるユーザーもいますが、実際にはそうではありません。
「GNOME Shell」に含まれる「JavaScript」はたかが10%であること、そして多くの処理で「JavaScript」は全く動作していないことを知るユーザーはほとんどいないでしょう。
もしユーザーがアプリとただ対話しているだけならば、その多くの時間「GNOME Shell」は、C言語で実装(コンパイル)されたネイティブマシンコードのみで動作しています。
誰がCPUやGPUを多く消費しているのか
通常パフォーマンスに関する調査を行う場合、まずCPUやGPUを多く消費している箇所を探し出します。一般的にプログラムのプロファイリングを行い、CPUやGPUを多く消費している箇所(ホットスポット)を探し出します。
そこじゃなかった
しかし「GNOME Shell」が遅い原因は、ホットスポットにはありませんでした。画面をスムーズに更新しない原因はアイドル時にあり、コールドスポットにありました。
CPUやGPUを多く消費している箇所にコールドスポットは存在しません。
プログラムの実時間の統計を見ることでコールドスポットの箇所を見つけ出します。
使用実時間
例えば「sleep 123」を実行すると、使用実時間は「123」になります。この時CPUやGPUを全く使用しませんが、処理が完了するまでしばらく時間がかかることが分かります。
シングルスレッドとイベントドリブン
「GNOME Shell」のようなシングルスレッドのイベントドリブンタイプのプログラムが費やす時間の大半は、「poll()」などコードの実行をブロックしシステムをアイドルにしている時間です。こうすることでユーザーがアプリと対話を行っていない時に、システムの消費電力を最小限に抑えることができます。
GNOME ShellとMutter
「GNOME Shell」と「Mutter」はシングルスレッドで「Glib」イベントループを使用します。そのため何かしらの処理待ちは、 次フレームの欠落や、描画や応答の突っかかりにつながります。
よくある処理待ちにはディスクI/OやGPU I/Oがありますが、「GNOME Shell」には次フレームの描画タイミングの計算ミスという問題もありました。
GNOME Shell 3.34で発見し修正した不具合
というわけで「Canonical(Ubuntu開発チーム)」は、「GNOME Shell 3.34」で使用実時間に関わる様々な不具合を修正しました。1.描画の計算ミスによりフレームが欠落する
この不具合はフレームのスケジューリングが数ミリ秒遅れることで発生する不具合です。この不具合は毎回発生するわけでは無いため、ユーザーは気づきにく不具合かも知れません。
本不具合修正後、一貫して高いスムーズなフレームレートになりました。
2.XorgではWaylandより1フレームラグがある
「Xorg」セッションでは、「Wayland」セッションと比較すると1フレーム遅れが発生する不具合です。アプリのウィンドウをドラッグすれば、この現象が見られるでしょう。
この不具合の原因は「1.」とは対照的に、次フレームのスケジューリングが早すぎるのが原因でした。
本不具合修正後、「Xorg」セッションで1フレームの遅延が解消されました。
3.カーソル移動のレートの制限とNVIDIA GPU環境でCPUの使用率が高くなる現象
様々なGPUドライバーをうまく扱うための仕組みがあり、この仕組みにより「Wayland」セッションではカーソル移動のレートが意図的に60Hzに制限されていました。またこの仕組みによりNVIDIA GPUを搭載する一部の環境では、「Xorg」セッションでCPUの使用率が100%になる現象が発生していました。
この不具合が修正され、カーソル移動のレートの制限がなくなり、CPUの使用率が高くなる現象も解消されました。
4.入力ラグ
入力イベントをシェルやアプリに伝えるタイミングに問題があり、ユーザーが入力デバイスを操作してから反映されるまでに遅延がありました。修正によりタッチパッドのスクロールなど入力遅延が1フレーム改善されました。
この不具合は部分的な修正に留まります。
完全な修正には問題が大きすぎるためです。
高解像度のタッチパッドのスクロールを行うには、「Xorg」セッションで「Chromium」を利用してください。
「Firefox」や「Wayland(XWayland)」セッションではまだ動作しません。
5.NVIDIA GPU環境で描画パフォーマンスが低くなる
「Xorg」セッションでは、CPUとGPUがお互いに並行して動作できるようにするため、また次フレームをスムーズに描画するため、CPUとGPUの性能が制限されていました。これは古いバージョンの「Mutter」にとってNVIDIA GPUドライバーが高速すぎるために導入された回避策です。
新しい「Mutter」では「3.」の修正によりこの回避策は不要になりました。
この修正によりNVIDIA GPU環境で描画pフォーマンスが高速化され、またスムーズな描画が行われるようになりました。
6.カーソル移動時のCPU使用率
カーソル移動時に同期を行うため、CPUとGPUの両方をブロックしパイプラインをストールする必要がありました。この処理をCPUでのみ行いGPUを使用しないように修正し、CPUの使用率が削減されました。
これによりデスクトップ全体の描画が止まらないようになり、結果的にシェルの実時間のパフォーマンスも向上しました。
まだ修正されていない不具合
以下の不具合はまだ修正されていません。「Ubuntu 20.04 LTS」&「GNOME 3.36」を目標に修正作業が行われます。
- Multi-monitor rendering in Wayland sessions spends some random fixed percentage of its time (average 50%) blocked, sleeping and unable to render the screen or respond to the user
- Mutter is still failing to schedule the next frame on time in some cases
さらなるパフォーマンスの向上を目指して
さらなるパフォーマンスの向上を目指し、継続的な取り組みが行われます。現在この取り組みには2つの目標が設定されています。
- 新しい/性能の高いPCで高速な動作
- 古い/性能の低いPCで高速な動作
「高速な動作」とは、ユーザーのディスプレイで滞り無くフルフレームレートで動作することです。
「新しい/性能の高いPC」とは、「Unity」や「GNOME」が普通に動作可能なPCを指します。
1.新しい/性能の高いPCで高速な動作
これを実現するには、まず実時間の遅延に関するすべての問題を解消する必要があります。さもないとどんなに高性能なPCを利用しても、遅延が発生する可能性があるためです。
この目標の実現に必要なことの多くは、すでに「Ubuntu 19.10/Mutter 3.34」で達成されています。
しかし目標を完遂するには、まだ取り組むべき課題がいくつかあります。
これらの課題は「Ubuntu 20.04 LTS/Mutter 3.36」を目標に取り組み、「Ubuntu 20.04 LTS」で完遂する予定です。
2.古い/性能の低いPCで高速な動作
これを実現するには、たとえ高性能なPCでも実時間に影響を与えるすべての課題を確実に解決しなければならないため、より困難な目標になります。計測の繰り返しによる問題の発見や継続的な修正が行われる予定です。
2020年に古い/性能の低いPCでも高速に動作する「GNOME」を提供できるよう、作業が行われます。
というわけで
「Ubuntu 19.10」では「GNOME」のパフォーマンスが大きく改善されています。「Ubuntu 20.04 LTS」ではさらに高速になった「GNOME」を体験できるようになるでしょう。
そして「Ubuntu 20.10」では、その体験をもっと幅広いユーザーに提供できるようになるでしょう。
ちなみに「Ubuntu Desktop」に対する取り組みは、「Desktop Team Updates」で毎週紹介されています。