VM上のwin10でネイティブマシンばりの性能を引き出す[win10 on CentOS7(kvm/qemu)]

# KVMでWindows10をサクサク動かす

## まえがき

みなさんは開発環境どうしてますか？
私は普段仕事ではMac上にVirtualBoxで立てたVMで開発しています。
最近だとdockerとか使ってる人も多いですよね。
Web開発はやっぱりMac便利だなーと思いつつも、社会人になるまでは10年以上Windowsオンリーで生きてきたので
Windowsでしか動かないシェアウェアやファイル形式を大量に溜め込んでいたり、
そもそもPCをパーツ単位で選んで組み立てるのが好きだったりするのでmacに移行できずにいるんですよね。

そこで、今回はLinux(CentOS7)上で
VMのLinuxの様々な種類のサーバを立てつつも、普段使いのVM上のWindows10で
ネイティブマシン並みの性能を引き出していく自分なりのチューニング方法についてお話していきます。

## そもそもなんでWin10のVMなのか

~~クラウド全盛期に何言ってんだって思われること請け合いだと思いますが~~**自宅サーバは楽しいぞ**

### メリット

- 好きなマシンを組めてたのしい
    - あこがれのCore i9 9900KとかXEONとか好きなの使えるぞ
    - 好きなだけメモリ積めるぞ
    - PCIパススルーすれば仮想マシンでもグラボ使えるぞ
    - ストレージ使いたい放題だぞ
    - 絶対クラウド破産しないぞ(パーツ破産はするかもね)
- いろんなOS使えてたのしい
    - インストールDVDのイメージがあればだいたいのOSが一台のマシンに載せられる、はず
- たのしい
- たのしい

### デメリット

- 電気代がかかる
    - マシン性能にもよりますが2,000円/月くらいは覚悟したほうがいいかもですね
- 最悪火事になる
    - よくネットでは使わなくなったノートpcを自宅サーバにしようぜ的な記事ありますがやめたほうがいいです
    - そもそも電源周りが24h365daysで動かす前提で出来ていない
    - 自分も最低でも2年に1度は電源ユニット交換してます
    - ラズパイとかもACアダプタあたりに気を付けたほうがいいと思います。

デメリットばっかりかいてる気もしますが、
便利な都会生活してると時々キャンプ行きたくなったり、
なんやかんやで賃貸より持ち家のほうが欲しくなったり
そういうのと結局一緒だと思いますよ。

## 前知識

### KVMとQEMU

QEMU(きゅーえみゅ)はハードウェア(マザボ(厳密にはチップセット)、PCIバス、USB、グラボ、HDD/SSD)などを
仮想マシンに仮想的に提供しています。
KVMというのはKernel-based Virtual Machineの略です。
仮想技術の一般化に伴ってIntel/AMDともにCPUに仮想化支援機能が搭載されており、それを使うのがKVMです。
特徴としてはOSを間に挟まないためオーバーヘッドが少なく、VMの動作が軽いことが挙げられます。

### ハードウェアの制限

上記でもCPUの仮想化支援機能を利用するといっていますが、
逆に言えば仮想化支援機能が搭載されていないCPUではKVMは利用できません。
必要要件は以下の3つ

- CPUが仮想化支援機能に対応していること
- マザボがIOMMU(パススルー)に対応していること
- GPUがUEFIに対応していること

詳しくは以下

#### CPU

Intel製CPUであれば `Intel VT-x` AMD製CPUであれば `AMD-V` が仮想化支援機能です。
対応CPUリストは
- [intel > Support Home > Product Specifications](https://ark.intel.com/content/www/us/en/ark/search/featurefilter.html?productType=873&2_VTX=True)
- [パソコン工房](https://www.pc-koubou.jp/magazine/5813)
などで確認してください。

#### グラボ

ゲームに限らず動画編集、マイニングなどGPUでやりたいことっていろいろありますよね。
仮想マシンでグラボを使うにはグラボそのものに必要な要件があります。
[Video BIOS Collection](https://www.techpowerup.com/vgabios/)に載っていればOKです。
ちなみに最初はこの要件を知らず、手持ちのGTX660(UEFI非対応)をパススルーしようとして2週間悩み続けた苦い経験があります。

## 本題

ここではLinux(CentOS7)上にWindows10マシンを立てて、グラボ、USBを普通のマシンと同じように使えるように設定していきます。
基本的な流れは

1. CPUの仮想化支援機能(Intel VT-x/AMD-V)を有効にする
2. グラボのパススルー設定
    1. IOMMUの有効化
    2. ホストマシンにグラボを忘れてもらう
3. kvm/qemu導入
4. ゲストマシン作成
    1. チューニング -> インストール
5. グラボのパススルー
6. USBのパススルー設定

### 1から2-2まで

正直このあたりはすでに紹介されている方も多いので下記リンクを参考にされるとよいです。
[かっこいいブログ名つけたい - 【Linux Mint】【QEMU/KVM】KVMによる仮想化Win10へのGPUパススルー設定](http://engetu21.hatenablog.com/entry/2018/04/03/003642)

#### 注意1：BIOSなのかUEFIなのか

ブートローダの変更反映ですが、BIOSなのかUEFIなのかでコマンドが異なります。
これが最初分からなくて2週間悩みました。グラボの件と合わせたら4週間ですね。
[CentOS7 ブートローダ周り](https://qiita.com/moukuto/items/c78f29f9bd1221baffca)にもありますが、

> ・BIOSの場合
> grub2-mkconfig -o /boot/grub2/grub.cfg
> ・UEFIの場合
> grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg

で編集を反映させましょう。
再起動させたのち、先ほどの

```bash
dmesg | grep -e DMAR -e IOMMU
```

で調べると `IOMMU enabled` が表示されるはずです。

### 注意2：グラボはホストマシン専用機にすること

BIOSの設定で利用するグラボはオンボードのものを選択して、モニタもオンボードにつないでおきましょう。
グラボは仮想マシンを起動した時点から仮想マシンにすべて持っていかれます。

### 3.kvm/qemu導入

ここについても特筆すべきことはないので下記リンクを参考に入れたらいいと思います。
[Server World - CentOS 7 - KVM:インストール](https://www.server-world.info/query?os=CentOS_7&p=kvm&f=1)


### 4.ゲストマシン作成

ついにゲストマシンを作成するときが来ました。
コマンド一発で作成する、対話シェルで作成する、GUIで作成するなど、様々な方法がありますが、お勧めはGUIです。
下記リンクを参考に進めていきますが手順[8]のFinishを押す手前で一旦止めてください。
[Server World - CentOS 7 - KVM:仮想マシン作成#2](https://www.server-world.info/query?os=CentOS_7&p=kvm&f=3)

#### チューニング

さて、手順通りにいけば今開いているウィンドウの真ん中あたりに `Customize Configuration before install` という項目があると思います。
この項目にチェックを入れてFinishを押すと詳細な設定に移れるのですが、
インストールをはじめてしまうと取り返しがつかない項目があるので必ずチェックを入れるのを忘れないでください。

1. 概要
    1. ファームウェア：UEFI
    2. チップセット：Q35
2. CPU
    1. 論理ホストCPU数(実CPUと同じもの)
    2. トポロジー
        1. ソケット数：1(推奨)
        2. コア数(実CPUと同じもの)
        3. スレッド数(実CPUと同じもの)
3. SATAディスク：SATA(推奨)
4. CD-ROM：SATA(推奨)

この辺は絶対やっておいた方がいいです。
CPUのチューニングに関しては[かっこいいブログ名つけたい - 【KVM/QEMU】仮想マシン(Win10)と実マシン(Win10)のベンチマーク比較（おまけで仮想ディスクベンチマーク）](http://engetu21.hatenablog.com/entry/2018/04/10/215621)が詳しいです。
ちなみに自分のマシンでもベンチマークをとってみたところ、
下記のように実CPU(Core i9 9900K)とそれなりに近い値をたたき出してくれています。
※濃い青が実速度、赤紫は参考のCore i9 9900K

![2019-08-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203936/432e3df9-b473-1d1b-d191-8fe7d63114d3.png)

きちんとゲストマシンからも16スレッド認識して3.60 GHzで稼働していることが分かります。
![2019-08-26 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203936/ada4a5b7-7682-1e22-8479-a0efad334472.png)

この状態でインストールを行い、セットアップが終了したら一旦シャットダウン。

#### グラボのパススルー

さて、ついにグラボをパススルーしていきます。
今まではグラフィックは全て一旦QEMUでエミュレートされてCPUで処理されていましたが、
この作業を行うと実マシン同様、グラフィックをグラボで処理するので処理速度がかなり向上します。

[かっこいいブログ名つけたい - 【Linux Mint】【QEMU/KVM】KVMによる仮想化Win10へのGPUパススルー設定](http://engetu21.hatenablog.com/entry/2018/04/03/003642)
上記ブログの `9.vendor id偽装` から進めればパススルー可能です。

#### USB(コントローラ)のパススルー

あとはオーディオもUSB-DAC経由で出したいなと思っていたのですが、
`ハードウェアを追加 > USBホストデバイス > USB-DAC` で追加したところ、
数秒に一回のペースでプツプツノイズが入ったり、時折激しくカクついたりするという問題が。
明らかにどこかで処理落ちしているような感じだったので調べてみたところ

[USBホストコントローラをPCIパススルー](https://blog.bitmeister.jp/?p=3773)

> フルスピードモード(12Mbps)なら簡単にできるけど、ハイスピードモード(480Mbps/USB2.0)を使うのは込み入った設定が必要

という記述を発見。
一次情報には当たれなかったけどこの情報を信じるならば、USBの転送速度に問題がある可能性は大いに高いので、
`ハードウェアを追加 > PCIホストデバイス > Intel Corporation Cannon Lake PCH USB 3.1 xHCI Host Controller`
を選択してUSB-DACをつなぐとすべてのノイズが消えました。

これで完全にVM上のWindowsが扱いとしてはネイティブマシンと同様になりました。
注意点としてはWindows起動時にはコントローラに刺したUSBは全てWindowsに回されるのでホストマシンの操作ができなくなります。
何かしたいときはsshかリモートデスクトップを使いましょう。

## おわりに

実に3か月くらいかけていろいろ作業してきましたが非常に楽しい毎日でした。
ブート周りや仮想デバイス、USBの速度、NVidiaのグラボのVendor id偽装など知らないことがたくさんでした。
みなさんもたまにはリアルコンピュータで遊んでみてはいかがでしょうか？
くれぐれも火事にはお気を付けください。乾燥する時期ですしね。