この記事は The Qt Blog の Performance Improvements with Qt 5.9 LTS を翻訳したものです。
執筆: Tuukka Turunen, 2017年5月31日
Qt 5.9 LTS では Qt Quick および QML のパフォーマンスが ARM 上の Linux 環境を中心に、劇的に改善されました。これまで QML のエンジンや Qt Quick の描画エンジン、QML コンパイラ、Qt Quick Controls などの領域でパフォーマンスの改善に力を入れてきました。パフォーマンスの改善は様々な領域に渡って大幅に改善しており、いくつかのアイテムでは一つ前の LTS Qt 5.6 と比較して数倍も高速になった部分もあります。
様々なプラットフォームにおいて、数々の最適化の効果を継続的に把握するために、いくつかのパフォーマンスのテストを定期的に実施しています。まだ自動化できていないテスト項目もありますが、これらの結果は testsresults.qt.io で公開しています。私たちは Qt がサポートしているすべてのプラットフォームや CPU アーキテクチャに対してパフォーマンスの改善に可能な限りの時間を割きたいと思っています。本記事では ARM 上での Linux は Qt 5.9 LTS で特に注力したターゲットのため取り上げていますが、その他のプラットフォームでもほぼ同じような改善がなされています。
Qt Quick アプリケーションの起動時間は、組み込み機器では非常に重要な要素です。小規模なシングルプロセスのシステムだけではなく、より複雑なマルチプロセスで動作する機器でもこれは同様です。Qt 5.3 以降、商用ライセンスでのみ利用可能な Qt Quick Compiler というツールを提供し、QML を C++ に変換し、C++ のコードとしてコンパイルすることで起動時間を改善できるようにしてきました。Qt 5.6 LTS から Qt 5.9 LTS の間、すべてのリリースで QML エンジン自体のパフォーマンスの改善が行われ、結果として起動時間の大幅な短縮が実現できるようになりました。Qt 5.8 で QML のキャッシュ機能を追加し、アプリケーションの2回目以降の起動時間の高速化が可能になりました。Qt 5.9 ではビルド時にキャッシュの生成が可能になり、これにより初回起動時からキャッシュを利用した起動時間の高速化の恩恵を受けられるようになりました。ちなみに、Qt Quick Compiler では初回起動時から起動時間は短縮されていました。
Qt 5.9 LTS と Qt Quick Compiler の恩恵の大きさはアプリケーションの機能や設計や実装に強く依存します。一般的に QML のコード量に応じてこの改善の恩恵は大きくなります。Qt 5.9 LTS では、商用ライセンスのみで提供している Qt Quick Compiler と、オープンソース版でも商用ライセンスでも利用可能な、ビルド時にキャッシュを生成するツールの2つのオプションが選択可能です。Qt 5.9 LTS でのパフォーマンスの改善と起動時間の短縮はどちらのアプローチでも実質同じ程度になります。
同じ Qt Quick のアプリケーションを Qt 5.6 LTS(Qt Quick Compiler なし)と Qt 5.9 LTS(Qt Quick Compiler あり/キャッシュを利用)で比較した結果、NXP i.MX6 では 60% 程度の改善が見られました。Qt 5.6 LTS(Qt Quick Compiler あり)と Qt 5.6 LTS(Qt Quick Compiler なし)の比較では、起動時間は 54% 改善されています。Qt 5.6 LTS(Qt Quick Compiler あり)と Qt 5.9 LTS(Qt Quick Compiler あり)で起動時間を比較したところ、NXP i.MX6 では 14% の改善が見られました。
この比較に用いたのは Qt Quick Controls 1 の gallery というアプリケーションで、ベンチマークは NXP i.MX6 と NVIDIA Tegra X1 で行いました。実際のユースケースにより近い結果を得るため、Qt Quick Controls 2 よりも処理の重い Qt Quick Controls 1 のアプリケーションを今回はあえて選択しました。Qt Quick アプリケーションの起動時間のより詳細な情報は、こちらのブログ記事 をご覧ください。また、高速起動に関するブログ記事のうち、特に2番目の こちらの記事 も是非ご確認ください。
Qt 5.6 LTS では Qt Quick Controls 1 が利用可能でしたが、Qt 5.9 LTS では Qt Quick Controls 2 が利用可能になっています。Qt Quick Controls 2 のリリース記事の とおり、Qt Quick Controls 2 はパフォーマンスに主眼をおいて設計自体の見直しを行いました。かなり初期の段階から、組み込み機器や組み込みシステムに向けた開発をしてきましたが、それ以外の Qt がサポートしているすべてのプラットフォームでも利用していただくことは可能です。Qt Widgets や Qt Quick Controls 1 とは異なり、Qt Quick Controls 2 はプラットフォームのルックアンドフィールが適用されません。専用のスタイルを複数提供するとともに、スタイル自体の開発も簡単にできるような仕組みを提供しています。設計の側面では、Qt Quick Controls 2 は C++ のパフォーマンスを最大限活かすようになっており、QML はアプリケーションから利用される API のみを提供するようになっています。
このグラフのとおり、パフォーマンスは大幅に改善されています(注:バーの高さが高いほどよいパフォーマンスになっています)。このベンチマークは NXP i.MX6 で行いました。Qt 5.9 LTS の Qt Quick Controls 2 と Qt 5.6 LTS の Qt Quick Controls 1 では、平均して6倍程度パフォーマンスが改善され、以前に比べて 14 倍も改善されたコントロールも存在します。この恩恵を得るためにはアプリケーションの Qt Quick Controls 2 対応が必要になりますが、Qt Quick Controls 2 はほぼすべての基本コントロールを提供しているので、この対応は基本的にはとても簡単な作業になります。対応の際には こちらのドキュメント をご覧ください。TableView など Qt Quick Controls 2 では現在提供していないコントロールも存在します。
こちらの記事で紹介した とおり、Qt 5.9 LTS では初回起動時に OpenGL のシェーダーのキャッシュを生成し、ディスクに保存する機能が追加されました。Qt Quick アプリケーションが OpenGL のシェーダーを利用している場合(これは一般的によくあることです)、これまでの Qt のリリースに対して起動時間の大幅な改善が見られます。Qt 5.6 LTS と Qt 5.9 LTS で、10個のシェーダーを利用した同じアプリケーションでベンチマークを取ると、シェーダーの初期化時間に大幅な改善が見られました。今回の計測で得られた改善の一部は描画の改善によるものですが、ほとんどの部分についてはシェーダーキャッシュ対応によるものになります。
同じハードウェア、同じ Qt Quick アプリケーションを使用して起動時間を計測したところ、Qt 5.9 LTS では Qt 5.6 LTS に対して7倍高速に起動するという結果が得られました。この記事の、一つ前のベンチマーク同様、この計測も NXP i.MX6 と Linux の組み合わせで行いました。このパフォーマンスの改善の効果はハードウェア、特に GPU に依存します。今回テストに使用したすべてのハードウェアにおいて大幅な改善が見られました。OpenGL のドライバ自体がキャッシュ機能を提供しているハードウェアでもパフォーマンスが向上しました。
Qt 5.8 では Qt の新しい設定システムを導入し、その他の改善も合わせてアプリケーションで利用される Qt ライブラリのバイナリのサイズの縮小化が可能になりました。この作業は Qt Lite プロジェクトという名前で行われ、アプリケーションのサイズを小さくすることにフォーカスして行われました。Qt 5.9 LTS では設定可能な項目の整備をし、様々なタイプのアプリケーションに対して最善の最小の Qt のライブラリのビルドを可能にしました。Qt 5.6 LTS でもアプリケーション全体のサイズを小さくすることは可能でしたが、ライブラリ単位での取捨選択や静的リンクによるものでした。Qt フレームワークの依存性の関係上、静的リンクによりリンカで削減できるサイズには限界があり、Qt Lite による機能の調整は更なるサイズの削減に貢献します。
このアプリケーションとそれに必要な Qt ライブラリ のバイナリサイズの比較には、samegame という比較的複雑な Qt Quick アプリケーションが使われました。Qt 5.6 LTS では動的リンクで 24.5MB 必要でした。静的リンクでは 13.8MB まで減らすことができました。Qt 5.9 LTS では Qt Lite による調整などをふくめて静的リンクで 5.4MB まで減らすことができました。パーセントでいうと、Qt 5.9 LTS のバイナリサイズは Qt 5.6 LTS と比較すると静的リンクを利用した場合 61% 小さくなりました。これによる機能の制限やアプリケーションの変更の必要はありません。
Qt 5.9 LTS での QML エンジンの改善により、JavaScript の実行時のパフォーマンスも改善されました。JavaScript をたくさん活用している Qt Quick アプリケーションでは、Qt 5.6 LTS と比較して、特に 64 ビットの ARM では、パフォーマンスが大きく改善されています。JavaScript を大規模に使用している例としては Canvas 3D 上での three.js の利用があげられますが、通常の Qt Quick アプリケーションの JavaScript はそれより小規模になるでしょう。
この計測は qtdeclarative リポジトリに含まれる v8-bench で行いました。testresults.qt.io ではその他のベンチマークの結果も公開しています。Qt 5.6 LTS と Qt 5.9 LTS の v8-bench によるパフォーマンスのベンチマークの結果を比較すると、32-bit ARM では 16% ですが、64-bit ARM では 302%(4倍の改善になります)の改善となりました。Qt 5.9 LTS で 64-bit ARM プロセッサの完全対応をしたことが後者の主な要因となります。
ここまで主な改善について紹介してきましたが、Qt 5.9 LTS の Qt Quick に対してはそれ以外にも様々な改善が行われてきました。様々なエリアに対してのチューニングが行われ、Qt フレームワーク内部の実行処理の最適化も行いました。様々な改善の裏側で、Qmlbench と呼ばれる Qt Quick の全般的なベンチマークスィートを定期的に実行し、改悪が行われないような努力も行われました。Qmlbench ツールでは、Qt Quick でよく使われる機能のパフォーマンスだけではなく、あまり使われない機能のパフォーマンスも可視化することができます。詳細は こちらのブログ記事 をご覧ください。
Qt 5.6 LTS と Qt 5.9 LTS を同様の環境での Qmlbench の結果の比較により、上記のグラフのとおり、いくつかの分野では 130% も改善できました。特に、レイアウトと複雑な文字列のパフォーマンスは劇的に改善されています。すべての Qmlbench のベンチマークの項目の平均的な改善率は Linux 上で 14% になりました。どのような機能が使われているかにもよりますが、Qt 5.6 LTS にくらべ、Qt 5.9 LTS での Qt Quick アプリケーションのパフォーマンスの向上はほとんどのケースで明らかであり、その差を実感できるレベルにあると思います。
このブログ記事では、Qt 5.9 LTS に対して行われたパフォーマンスの改善のうちのいくつかを紹介しました。同じアプリケーションを Qt 5.9 LTS で動かした場合、Qt 5.6 LTS と比較してパフォーマンスは劇的に向上しています。アプリケーションの変更は必要なく、Qt 5.9 LTS でコンパイルするだけでこれらのパフォーマンスの改善の恩恵を受けることができます。起動時間の短縮やバイナリサイズの縮小化、描画のパフォーマンスの改善など、Qt 5.9 LTS はパフォーマンスという側面では非常に大きな前進になりました。Qt Quick Controls 2 などの新機能も含めると、Qt 5.9 LTS のパフォーマンスの改善はさらに大きくなります。
今回の記事はお役に立ちそうでしょうか? Qt 5.9.0 は本日リリースされました。オンラインインストーラー経由や、Qt Account から、もしくは Qt のダウンロードページ(オープンソースユーザー向け)から入手することが可能ですので、是非お試しください。
Qt 5.9 の LTS の詳細については、こちらの記事 も是非ご覧ください。