ファイル処理のパフォーマンスが大幅に向上
KDE 環境で大量のファイルをコピーする時に、ファイル処理のパフォーマンスが大幅に向上しました。12年前に報告された不具合
時は今から約12年前に遡ります。約20~40KB程度の小さなサイズ約300万ファイルを含む15GBのフォルダーをコピーした時に、ファイルのコピー処理が完了するのに KDE では5~10時間もかかったとの不具合が報告されました。
またファイルのコピーが完了するまで、デスクトップ全体の動作が重くなったとのことです。
その一方で rsync を使用して同フォルダーをコピーした場合は、約20分でコピーが完了したと報告されています。
報告者の環境は、以下のようになっています。
- CPU:Intel Core i7-3820
- ストレージ(HDD):Western Digital WD Blue 500GB 16MB Cache SATA 3.0Gb/s 3.5インチ
- ファイルシステム:ext4
CPU が時代を感じさせますね。
KIO にボトルネックがある
調査の結果、KIO(KDE Input/Output)にボトルネックがあることが分かりました。KIO はローカル及びネットワーク上のファイル含め、ファイル管理を透過的に行うためのライブラリーです。
例えばファイルマネージャーの Dolphin は KIO を利用しており、KIO を経由してファイルを操作することで、ファイルがローカルにあろうとも、ネットワーク上にあろうとも、同じようにファイルを操作できるようになります。
KIO のおかげでアプリの実装コストを大幅に下げることができます。
また KIO は KDE Frameworks の一部として提供されており、KDE 環境で幅広く活用されているライブラリーです。
別プロセスでファイルを処理している
GUI アプリの開発者であれば、ファイルのコピー等処理に時間がかかるアクションを実行する際、UI を止めない設計を考えるかと思います。UI を止めないとは、UI がユーザーやシステムに応答できる状態を維持するということであり、UI/UX の観点から必ず必要になる要素ですね。
この時 UI を止めない方法として、イベントループを活用する方法や、マルチスレッドにする方法、別プロセスで処理を実行する方法が考えられます。
要件にも寄りますが実装コストやパフォーマンスを加味すると、マルチスレッドの手法がよく検討されるのではないでしょうか。
さて KIO はプロトコルごとに別プロセスで処理を実行します。
この時 KIO を利用するアプリとは IPC(プロセス間通信)で繋がっており、ソケットを経由してデータをやり取りします。
IPC による利点は堅牢性であり、プロセスがクラッシュしてもアプリを巻き込まず復帰が容易になります。
欠点はプロセス間のやり取りにコストがかかることです。
KIO はローカルファイルのファイル操作に関しても、別プロセスで処理を実行していました。そのため1ファイルごとに IPC によるデータのやり取りが発生しており、それがボトルネックの主因になっていました。
なぜ別プロセスで実行を?
時代は2000年頃の KDE 2 の時代まで遡ります。この頃 Linux で実用的なスレッド環境がまだ整っていなかった時代であり、Linux で NPTL(Native POSIX Thread Library)がサポートされたのは、2003年にリリースされた Linux 2.6 からでした。
そのため当時の時代背景では、プロセスの分離及びソケットによる IPC が合理的な選択肢になっていました。
ローカルファイルはスレッドでいいんじゃない?
プロセス分離の設計手法は、ネットワークプロトコルに関しては現在でも有効な手法です。ネットワークは信頼性の確保が難しく、プロセスの分離の利点が強く働きます。
その一方でローカルファイルに関しては多くのアプリで実績があるように、マルチスレッドと比べプロセス分離の利点を十分に正当化できるほどの理由が見当たりません。
そして2022年に登場した KDE Frameworks 5.95 で、KIO はアプリ内のスレッドでローカルファイルを処理するようになりました。
問題の解決はまだ早い
これで問題が解消されるかと思いきや、実はまだ問題が残っていました。アプリとローカルファイルを処理するスレッド間で、プロセス間での通信方法と同様にソケットによる通信を行っていました。
これによりソケットによるコストが残ったままになっていました。
そもそもスレッド間の通信であれば、ソケットを経由せず直接メモリー上でデータのやり取りが可能です。
というわけでこの実装も修正され、KDE Frameworks 6.29 で問題が改善されることになります。
問題の解決はまだまだ早い(今後の予定)
これまでの改善作業でパフォーマンスは大幅に改善されました。例えば4KBのファイルを5,000個コピーする時に今まで1.6秒かかっていた処理が、0.4秒まで短縮されました。
しかしまだ改善の余地があります。
現状はファイル一つ一つにジョブを生成しています。
例えば3万個のファイルをコピーする場合、3万個のジョブが生成されています。
これを可能な限り一つのジョブにまとめることで、ジョブ生成にかかるコストを削減できます。
同様の例でこの改善を入れた場合さらにパフォーマンスが向上し、0.09秒まで短縮されます。
これは cp -r を実行した時と同等のパフォーマンスになっています。
現在この改良は作業中であり、うまくけば今後この改良が KDE Frameworks 6.29 よりも後にリリースされる KDE Frameworks で搭載されることになります。
