rcmdnk's blog

【WSLオフィシャル販売】Groundswell メンズ Tシャツ/Groundswell Mens Tee

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 を入手する

ただ、結構問題が起きてる様なので、無理に急いで上げるのは避けたほうが良いかもしれません。

「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すでにとかを入れている場合、更新プログラムパッケージを使って更新する必要があります。

WSL 2 Linux カーネルの更新 Microsoft Docs

から更新プログラムパッケージをダウンロードして実行します。

実行後、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を使ってます。

Sponsored Links
Sponsored Links

« Windows Terminalを試す WindowsのGoogle日本語入力+Chrome+Grammarlyで入力文字が消えてしまうバグ(ChromeやGmailのせいではない) »