WindowsのWindows Subsystem for Linux (WSL)のバージョン2 (WSL2)が 正式にリリースされ、最新のWindowsアップデートを行うことで 使える様になりました。
ということでちょっと使ってみましたが、プロセスによってはかなり速くなってそうです。
Windows Subysytem for Linux (WSL)
Windows Subysytem for Linux (WSL)はWindows上でLinuxの実行環境を作るシステムです。
以前もサードパーティーなCygwinの様なものはありましたが、 Windowsネイティブで、というところで期待されています。
WSL 1では独自のサブシステムを作ってLinuxの実行環境を作っていました。
WSL 2では仮想マシンでLinuxカーネルを動かしてホントのLinux環境になります。
これによってWSL 1では互換性がなかったLinuxのソフトウェアなども問題なく動かせる様になります。
Windowsでの仮想マシンの利用、というのは以前もありましたが、 WSLではMacとかでターミナルを立ち上げる感覚でシステムごと立ち上げる事ができ 今まで使っていた仮想マシン環境とはかなり感覚的に違うものになっています。
WSL2のインストール
まずはWindowsをバージョン19041以上にする必要があります。
これはつい先日配信が開始された May 2020 Updateを入れると入ります。
ただし、今回はその前にInsider Programで入れて19041以上にしてやっています。 (ちょうどWSL2試そうと思ったタイミングで正式リリースが来てしまった。。。)
May 2020 Updateがまだ来て無くてInsider Programを入れたくない場合は 以下に従ってMay 2020 Updateを入手:
ただ、結構問題が起きてる様なので、無理に急いで上げるのは避けたほうが良いかもしれません。
「Windows 10 May 2020 Update」でブルースクリーン発生やBluetooth未接続、一部アプリでIME不具合 - PC Watch
WSL2のインストールは以下に従って。
Windows Subsystem for Linux (WSL) を Windows 10 にインストールする Microsoft Docs
WSLが入ってない場合はまずPowerShellを管理者権限で起動して(Windowsのスタートボタンを右クリック、から)
PS C:\WINDOWS\system32> dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
もう一つ、”仮想マシン プラットフォーム” のオプション コンポーネントを有効にするために
PS C:\WINDOWS\system32> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
を実行して再起動。
再起動後、WSL2をデフォルトにするため、管理者権限で立ち上げたPowerShellから
PS C:\WINDOWS\system32> wsl --set-default-version 2
を実行します。これで今後入れるLinuxディストリビューションがWSL2として動きます。
すでにUbuntuすでにとかを入れている場合、更新プログラムパッケージを使って更新する必要があります。
から更新プログラムパッケージをダウンロードして実行します。
実行後、PowerShellを管理者権限で立ち上げて インストール済のLinuxディストリビューションをWSL2にします。
PS C:\WINDOWS\system32> wsl -l
Linux 用 Windows サブシステム ディストリビューション:
Ubuntu (既定)
PS C:\WINDOWS\system32> wsl --list --verbose
NAME STATE VERSION
* Ubuntu Running 1
現在はUbuntuがWSL1で入っています。 これをWSL2に変更。
上でRunning
になってますが、WSLを立ち上げていても、以下のコマンドを実行すると
強制的に終了するので、
WSL側の作業はちゃんと終了してからやってください。
PS C:\WINDOWS\system32> wsl --set-version Ubuntu 2
変換中です。この処理には数分かかることがあります...
WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してください
変換が完了しました。
PS C:\WINDOWS\system32>
PS C:\WINDOWS\system32> wsl -l -v
NAME STATE VERSION
* Ubuntu Stopped 2
PS C:\WINDOWS\system32>
ちなみに恐らくWSLの中で使っているファイルの数とかに関係あるとは思うんですが、 今回上のコマンドをやってみた所、30分近くかかりました。
さらに実行中に他のことしてたら、 多分ファイルのIOが激しいからだと思いますが、 時々不安定になることがあって作業に支障をきたす位でした。
なのでやるなら夜中とか使わない時にやった方が良いと思います。
もし、更新プログラムパッケージを適用してないと
PS C:\WINDOWS\system32> wsl --set-version Ubuntu 2
変換中です。この処理には数分かかることがあります...
WSL 2 を実行するには、カーネル コンポーネントの更新が必要です。詳細については https://aka.ms/wsl2kernel を参照してください
PS C:\WINDOWS\system32>
的なメッセージが出ます。
パフォーマンスチェック
WSL 2ではファイルIOなどかなり改善されている、ということだったのでちょっとテストしてみました。
テスト環境は
- WSLのOS: 18.04.2 LTS (Bionic Beaver)
- CPU: Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz
- Memory: 16696168 kB (/proc/meminfo)
ファイルの生成削除
以下のコマンドを実行
$ x=$(seq 1 1000)
$ time for i in $x;do rm -f file && touch file;done
-
WSL 1
real 0m10.056s user 0m0.406s sys 0m7.922s
-
WSL 2
real 0m0.949s user 0m0.281s sys 0m0.226s
WSL 2の方が10倍位速くなっています。
ddでのチェック
以下を実行
$ for i in $(seq 1 10);do sleep 1;dd if=/dev/zero of=/tmp/write$1.tmp ibs=1M obs=1M count=1024 2>&1|grep -v "^1024+0";done
-
WSL 1
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.30206 s, 3.6 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.295579 s, 3.6 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.300499 s, 3.6 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.295048 s, 3.6 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.298456 s, 3.6 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.298082 s, 3.6 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.297875 s, 3.6 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.305186 s, 3.5 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.39612 s, 769 MB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.297403 s, 3.6 GB/s
-
WSL 2
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.640851 s, 1.7 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.660463 s, 1.6 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.648255 s, 1.7 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.656519 s, 1.6 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.65121 s, 1.6 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.651856 s, 1.6 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.665299 s, 1.6 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.723154 s, 1.5 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.707145 s, 1.5 GB/s 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.711927 s, 1.5 GB/s
これはなぜかWSL 1の方が倍くらい速い。
何度かチェックしてみてるんですが変わりません。
上のチェックで大きくWSL 2の方が速かったのにちょっとこの結果の意味はよくわかってません。
サブシェルチェック
Cygwinとかを使ってて異常に遅いな、と感じるのはサブシェルを立ち上げる様なプロセスが 走っているときでした。
システム上、別のプロセスを立ち上げる様なことが通常のLinuxとかに比べて格段に遅くなるようです。
同様にWSLを使ってみた時もサブシェルを立ち上げると遅くなるな、と感じてました。
ということでそのチェック。
以下を実行
$ x=$(seq 1 10000)
$ j=0; time for i in $x;do j=$(expr $j + 1);done
-
WSL 1
real 0m49.069s user 0m2.406s sys 0m37.063s
-
WSL 2
real 0m5.699s user 0m0.855s sys 0m1.192s
ということでこれもWSL 2の方が10倍位速くなっています。
同じ作業をサブシェルを作らずに行うには以下の様なコマンドが使えます。
$ x=$(seq 1 10000)
$ j=0; time for i in $x;do ((j++));done
これだと
-
WSL 1
real 0m0.043s user 0m0.016s sys 0m0.031s
-
WSL 2
real 0m0.014s user 0m0.014s sys 0m0.000s
WSL 1でも上のWSL 2より格段に速くなっています。速すぎて正確さに欠けますが、 ここでもWSL 2の方が速くはなってます。
サブシェルチェック 2
別のコマンドでチェック
$ x=$(seq 1 1000)
$ time for i in $x;do a="XXXabcXXX";a=$(echo $a|sed "s/abc/def/");done
-
WSL 1
real 0m8.042s user 0m0.344s sys 0m6.344s
-
WSL 2
real 0m1.004s user 0m1.158s sys 0m0.137s
これも約10倍くらいの差。
同様のことをサブシェルなしだと
$ x=$(seq 1 1000)
$ time for i in $x;do a=XXXabcXXX;a=${a/abc/def};done
-
WSL 1
real 0m0.006s user 0m0.016s sys 0m0.000s
-
WSL 2
real 0m0.003s user 0m0.001s sys 0m0.002s
ということで、WSL 2の方が速い、ですが、こういったことは通常でも なるべくサブシェルを使わずにやった方が圧倒的に速くなります。
git clone
ファイルの書き込みを多く行うgit clone
とかが速くなった、という話を見たのでチェック。
$ [email protected]:rcmdnk/rcmdnk.github.io.git
$ (time git clone $repo >&/dev/null) 2>&1|tr '\n' ' '|tr '\t' ' '
自分のレポジトリで大きそうなもの(このブログのレポジトリ)でチェック。 サイズはclone後に337MBほどでした。
-
WSL 1
real 0m47.073s user 0m3.891s sys 0m3.453s real 0m26.106s user 0m2.859s sys 0m2.766s real 0m27.844s user 0m2.828s sys 0m3.000s real 0m26.955s user 0m2.844s sys 0m3.078s real 0m38.123s user 0m3.156s sys 0m2.922s real 1m0.090s user 0m3.969s sys 0m3.750s real 0m43.652s user 0m3.313s sys 0m3.297s real 0m30.926s user 0m2.891s sys 0m3.297s real 0m25.048s user 0m3.156s sys 0m2.797s real 0m23.092s user 0m2.813s sys 0m2.391s
-
WSL 2
real 0m26.673s user 0m3.694s sys 0m1.374s real 0m26.953s user 0m4.328s sys 0m1.648s real 0m33.887s user 0m4.457s sys 0m2.148s real 0m53.725s user 0m5.659s sys 0m2.902s real 1m9.217s user 0m5.338s sys 0m2.212s real 0m30.451s user 0m3.649s sys 0m1.246s real 0m38.896s user 0m4.234s sys 0m1.693s real 1m0.555s user 0m4.976s sys 0m2.448s real 0m18.706s user 0m4.446s sys 0m1.277s real 0m17.233s user 0m3.457s sys 0m0.910s
ムラがありますが全体的にはWSL 2の方が速い。 ただ恐らくネットワーク的なムラが原因なのかな、という感じもあるので余り 意味のある結果ではないかもしれません。
まとめ
ということで、軽くパフォーマンスを見てみた所、 差があるところで10倍くらいWSL 2の方が速くなっていました。
WSL 2が使える環境であれば特にデメリットも無いと思うのでWSL 2に上げた方が良いと思います。
すでに使ってるものを2に上げるのはちょっと時間がかかるので時間に余裕がある時にやったほうが良いですが。
ちょっと性能が低いPCだとWSL 1だと立ち上げるだけでも結構時間がかかって余り使いたくないものだったかもしれませんが、 WSL 2なら使えるかもしれません。
その他で気づいたことはまだ無いですが、今は結構使ってるのでまた なにか気づいたら書いていこうと思います。
ddの結果は謎。
ちなみにターミナルとしてはWindows Terminalを使おうと思ってたんですが ちょっと使いづらいところがあったので今はwslttyを使ってます。