今回は、前回の続きで、wsl$ファイルシステムについて解説し、WSLのそれぞれのファイルシステム(表01)を比較することにする。なお、WSL側ファイルシステムやドライブファイルシステムなどに関しては、前回の記事を参照していただきたい。
■バックナンバー
・Windows Subsystem for Linuxガイド 第4回 ファイルシステム編
https://news.mynavi.jp/article/20220303-2284619/
・Windows Subsystem for Linuxガイド 第3回 WSL2動作設定編
https://news.mynavi.jp/article/20220207-2266984/
・Windows Subsystem for Linuxガイド 第2回 コマンド編
https://news.mynavi.jp/article/20211228-2240002/
・Windows Subsystem for Linuxガイド 第1回 基本編
https://news.mynavi.jp/article/20211203-2211548/
wsl$ファイルシステム
Win32側からWSL側ファイルシステムをアクセスできるようにするのがwsl$ファイルシステムだ。wsl$ファイルシステム(およびドライブファイルシステム)では、異質のファイルシステムをアクセスする点に注意が必要だ。
wsl$ファイルシステムは、WSL1でもWSL2でも、9Pを使ったネットワーク共有になっており、仮想的なホストwsl$を使ったUNC(Universal Naming Convention。Uniform ~ともいう。Windowsのネットワークパス記法)でアクセスが可能になる。このとき、それぞれのディストリビューションへのアクセスは、ディストリビューション名(wsl.exe -lが表示する名称)を共有名として利用する。たとえば、Ubuntu 20.04 LTSの場合、ディストリビューション名は、Ubuntu-20.04となるため、“\\wsl$\Ubuntu-20.04”でアクセスが可能になる。なお、Windows 11では、“\\wsl.localhost\Ubuntu-20.04”としてもアクセスが可能だ。
コマンドラインからのアクセスなら、上記のUNCパスを使えば、WSL側ファイルシステムへのアクセスが行える。
なお、Windowsでは、UNCパスの先頭部分では、ファイルパスの補完機能が働かないため、上記のWSLディストリビューション名を含めたUNCパスの先頭部分は覚えておく必要がある。ただし、ディストリビューション名の後ろのルートファイルシステムからは補完が働くようになる。
エクスプローラーを使う場合、Windows 11では、左側の「ナビゲーションペイン」に「Linux」フォルダーがあり、その下に各ディストリビューション名が並ぶ(写真01)。Windows 10では、「ネットワーク」フォルダーで、アドレス欄を使って“//wsl$/”を開くことで、各ディストリビューションのフォルダーが見えるようになる(写真02)。Windows 11と違い、ナビゲーションウィンドウに表示されないが、このように手動でUNCを指定することで、エクスプローラー内に表示されるようになる。また、ショートカットの作成は可能なので、クイックアクセスに登録する、適当なフォルダーにショートカットを作って置くことで簡単に開くことが可能になる。
いったん、wsl$ファイルシステムを開けば、あとは通常のエクスプローラーと同じように利用することが可能だ。たとえば、ドラッグ&ドロップやコピー&ペーストでWSLディストリビューション間のファイルコピー、移動が行える。
WSLには、ディストリビューション間で相互にファイルアクセスを行う機能はないが、wsl$ファイルシステムを使うことで、Win32側からエクスプローラーを使って、ディストリビューション間のファイルのコピー、移動が行える。
ただし、Win32側とWSL側では、ファイルのアクセス許可が個別に管理されている点には注意が必要だ。たとえば、WSL側で開くのに管理者権限が必要な場合、Windows側でもこれを開くことができない。また、PowerShellなどで、資格を指定してのアクセス、たとえば、“get-content -credential administrator”を使ってもアクセスができない。こうしたファイルに関しては、WSL側で管理者権限を使って操作する必要がある。逆に、WSL側で管理者権限を使ってもWindows側でアクセスに制限がかけられているファイルを開くこともできない。このあたりは、別途ファイルのアクセス権として解説予定なので、とりあえずは、wsl$ファイルシステム(およびドライブファイルシステム)に関しては、個別にアクセス権管理が行われていると理解しておいてほしい。
また、後述するように9pを使ったネットワークファイルシステムは、プロトコルによるオーバーヘッドが存在し、必ずしもローカルファイルシステムと同等の速度でないことには注意が必要だ。
WSLのファイルシステムを比較する
WSL側では、(表02)のようなファイルシステムが動作している。ここでは、これらのファイルシステムのアクセス性能について簡単なベンチマークを行い、その性能を見ていくことにする。
WSLのファイルシステムは、Linux標準のものではなく、WSLという環境で利用される特殊なもの。具体的には、ext4を除くと、Linux側に、ファイルシステムに対応するブロックデバイスが存在しない。このため、通常のファイルシステム用ベンチマークソフトウェアが利用できないことが多い。
このため、簡易な方法として、ddコマンドを使ってファイルの読み書き速度を測定する。ddコマンドは、ファイルを書き込み、読み出しするコマンドで、読み書きに要した時間や転送速度を表示する機能がある。また、読み書きの単位となるブロックサイズを指定することができるため、これを変更することで、ファイルシステムの性能を簡易に予測することが可能だ。一般にファイルシステムの読み書き速度は、一回の読み書きに使うブロックサイズに比例して早くなる。
今回は、ブロックサイズを4キロバイト、32キロバイト、256キロバイト、2メガバイト、16メガバイトの5つで1ギガバイトのファイルを読み書きしてみた。
なお、実際の利用では、アプリケーションがファイルの読み書きを行い、ファイルサイズもさまざまであることが多い。このため、このddコマンドで得られた結果がただちにアプリケーションでのファイルの読み書き速度となるとは限らない。
WSL側ファイルシステムの場合
まずは、WSL側ファイルシステムだが、これには、WSL1のwslfsとWSL2のext4がある。その結果を図01と表03に示す。グレーがWSL1のwslfs、オレンジがWSL2のext4に対応している。実線が読み出し(Read)、点線が書き込み(Write)である。
このグラフからわかることは、ブロックサイズが小さいうちはwslfsが高速だが、ブロックサイズが大きくなるにつれてext4が高速になることだ。WSL1とWSL2は同一ディストリビューションでは、どちらか1つ(排他)でしか選択できず、利用するアプリケーションにより選択を行う必要がある。WSL2は、そもそも、WSL側ファイルシステムを高速化するために仮想マシンを使い、仮想ハードディスクファイルで、Linuxネイティブのext4ファイルシステムを実現した。このことから考えても、WSL側ファイルシステムが大容量ファイルを扱うような場合には、WSL2が有利といえる。
ドライブファイルシステムの場合
Win32側のファイルシステムをアクセスするためのドライブファイルシステムは、WSL1では、drvfsが使われ、WSL2では、9pファイルシステムが利用される。前者は、LinuxカーネルのVFS(仮想ファイルシステム)をWindowsのファイルアクセス用カーネル呼び出しに変換するもの。9pは、ネットワークファイルシステム用の9Pというプロトコルを経由して、Win32側の9pサーバーモジュールがNTFSをアクセスする。
図02と表04は、そのベンチマーク結果だ。グレーがWSL1の場合、オレンジがWSL2の場合で、実線が読み出し(Read)、点線が書き込み(Write)である。
このグラフからわかるのは、WSL2のドライブファイルシステムは、読み書きともにあまり速くないという点だ。WSL2を利用する場合には、この点に注意する必要がある。wsl.exeコマンドによるWSLの起動では、カレントフォルダーが起動フォルダーとなるため、うっかり、大きなファイルを作成してしまうなどすると、かなり時間がかかってしまうことがある。できれば、Linuxのユーザーディレクトリなどをカレントディレクトリとして起動するようにしたほうがよい。このような場合、Win32側では、wsl$ファイルシステムのパスを利用することができる。
wsl$ファイルシステムの場合
wsl$ファイルシステムは、Win32側から利用するものなので、ddコマンドが利用できない。このため、似たような測定ができるWindows用のCrystalDiskMark(8.0.4。x64版)を使って、NTFSローカルファイルシステム、wsl$ファイルシステム(WSL1とWSL2)、ネットワークファイルシステムの速度を測定してみた。wsl$ファイルシステムは、Ubuntuディストリビューションを使い、WSL1とWSL2の両方の場合で測定を行った。
ブロックサイズは4キロバイト、128キロバイト、1メガバイト、8メガバイトの4種類。キュー数は16、スレッド数は1とした。その結果が図03と表05だ。
これらから見るとおり、ローカルのSSDよりは遅いが、ギガビットイーサーネットによるネットワークファイル共有よりは高速である。ただし、wsl$ファイルシステムの書き込み速度に関しては、ギガビットイーサーネットによるネットワーク共有とそれほど大きく違わない。
また、WSL1とWSL2では、ドライブファイルシステムの速度がわずかに異なる。これは、Win32側は同じでもWSL側の9pサーバーの実装が異なるためだと思われる。
WSLでのファイル処理
WSL2では、WSL側ファイルシステムでは高速な処理が可能になることから、ファイルを反復してアクセスする場合などにはext4側にコピーするほうが有利になる。
ただし、WSL2でのドライブファイルシステムからWSL側ファイルシステムへのコピーは、9pファイルシステムの読み出し速度が速くないため、必ずしもコピーを行うことが有効ではない点にも注意されたい。一回のみのファイルの読み書きなら、コピーせず、そのままドライブファイルシステムを経由してアクセスするほうが時間が短くなる。特にファイルがあまり大きくない場合には、どちらも体感的には同じような結果になるだろう。
実際のファイル読み書き効率は、アプリケーションがファイルを読み書きするパターンに依存する。ファイルの読み書きアクセスがアプリケーションを律速するようなもので、ある程度長い期間、開発が継続しているようなものであれば、ファイルの読み書きを最適化している可能性がある。このような場合、ext4側にファイルを置くのがベストだと考えられる。
WSLでは、残念ながら、ファイルの読み書きについて、物理ハードウェア上のLinuxと同等の性能というわけにはいかない。また、Win32側からの読み書きについても同様だ。このため、ある程度大きなファイルを扱う、ファイルを繰り返し読み書きするという場合には、どのファイルシステムを使うかで実行時間に差がでてしまうことがある。基本は、異なるファイルシステム側への多数、あるいは大量ファイルの読み書きを避けるという点だ。