VTune Profilerで性能のボトルネックを特定する方法について

# はじめに

この記事ではIntelから無償で提供されているプロファイリングツールであるVTune Profilerの基本的な使い方を解説します。
手探りで使い方を模索している状況なので、より良い使い方が存在したり、あるいは明確な誤りが含まれている可能性があることにご注意ください。

# VTune Profilerとは?

VTune ProfilerはIntel社から提供されている無償のプロファイリングツールです。
アプリケーションやミドルウェアの性能のボトルネックの解析に利用できます。
※仕事でMySQLやPostgreSQL原因不明の性能劣化に遭遇した際に非常に役に立ちました

[Intel VTune Profiler](https://www.intel.com/content/www/us/en/developer/tools/oneapi/vtune-profiler.html)

IDEのプロファイリング機能やperfコマンドを使ったことがあるくらいで、そのほかのプロファイリングツールに精通しているわけではないですが、軽く使った限りでは以下のような利点があります。

- 無償で利用できます
   - [ライセンス条項(Intel End User License Agreement for Developer Tools)](https://www.intel.com/content/www/us/en/developer/articles/license/end-user-license-agreement.html)を読む限りでは、恐らく商用にも利用できる（はず） ※ライセンス条項はご自身でご確認ください
   - OSSではないようです
- マルチプラットフォーム対応です
   - GUIを起動するホスト側のOSとしてはLinux, Windows, Macに対応しているようです。
   - プロファイリング対象としては、Linux, Windows, FreeBSDに対応しているようです(AndoridはIntelプラットフォームのみなので実質無意味)
- GUIで直感的な操作できます
   - プロファイリング対象に対するツールのデプロイ等をの各種操作を非常に直感的に実施できます
   - 難しい専門用語も、大抵はマウスオーバーで詳細な説明を表示できます
   - 単に記録した数値を表示するだけではなく、問題があるかどうかの判断までやってくれます
   - CLI版も提供されています
   - GUIの操作はWindows、プロファイリング対象はリモートのLinuxといった使い方も実施できます。この場合もボタン一つでプロファイリング対象にバイナリをデプロイできます。
- CPU内臓のPMUから情報を取得するのでオーバーヘッドが少ないです
   - ドライバーをインストールする必要のない、ユーザーモードでのサンプリングもサポートしてます(ただし、オーバーヘッドが大きいようです) 
- Intel CPUのPerformance Monitoring Eventも確認できます
   - [PMUから提供されるPerformance Monitoring Event](https://perfmon-events.intel.com/)も取得可能であり、コード上のボトルネックだけではなく、CPUのマイクロアーキテクチャのどこがボトルネックとなっているのかも確認できます。
- 複数のプログラミング言語/処理系に対応しています
   - C, C++, C#, Fortran, Golang, Java, Python, .NETに対応しているようです。
- 公式ドキュメントの品質が高いです
   - [Intel VTune Profiler User Guide](https://www.intel.com/content/www/us/en/develop/documentation/vtune-help/top.html)の品質が高く、説明が詳細かつ網羅的であるだけではなく、多数のサンプルやレシピなどの情報も含まれています。
- 無料でもサポートしてくれます
   - コミュニティサポートですが、無料でもサポートを実施してくれます。一件問い合わせを行いましたが、レスポンスの早さ、品質ともにしっかりしている印象です。

一方で簡単な使い方をしている限りでは、以下の点には注意する必要がありそうです。

- 基本的にIntel CPU用です
    - 公式では「3rd generation Intel Xeon processor family v3 (or later)
4th generation (or later) Intel Core™ processor」とされており、10年程度前のCPUまではサポートしているようです。
    - User-Mode SamplingならばAMD CPUでも動くようですが、サポート対象外ですし何らかの不具合があったり、CPUのモデルナンバーで弾かれるようになる可能性があるので、基本的にIntel CPU用だと思われます。  
- 一部のIntel CPUはサポートしていません
    - 古いCPUでは未サポートですし、比較的新しくとも言及が一切ないAtomの系譜のCPUは中途半端にしかサポートしていないようです。
    - 以前はマイクロアーキテクチャの分析を実施できていたGemini Lake(Celeron J4005)で実施できなくなったり、メモリ帯域の分析などはPMUにそのための機能が実装されていないことからエラーになったりと、Atomの系譜のCPUのサポートは怪しいようです。
- プロファイリング対象のデータ量が大きい場合、GUIの操作が重くなるようです
    - 数百スレッド、数分のプロファイリングをGUIで描写するのはそれなりの負荷がかかるようです。
    - 分単位のサンプリングを実施すると簡単にGiB単位でストレージ容量が消費されることにも要注意！
- クラウド環境での利用はuser-mode samplingのみに対応しています
    - [クラウド環境はサポートされている](https://www.intel.com/content/www/us/en/develop/documentation/vtune-help/top/set-up-analysis-target/targets-in-a-cloud-environment.html)ものの、仮想化されたクラウド環境では直接PMUにアクセスできないことから、Bare Metalを除き、user-mode samplingのみを実施できるようです。
       - 厳密にいえば、[2ソケットをまるごと利用する巨大なインスタンスタイプではハードウェアイベントを取得できそう](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-vtune-amplifier-functionality-on-aws-instances.html)なのですが、 プロファイリングのためだけにr5.12xlargeやm6i.16xlargeを利用することは普通はないと思われます。
- マルチプロセス構成のアプリケーションでは、アプリケーションの起動から実施する必要があります
    - Attach to Processの機能では特定プロセス「のみ」のプロファイリングを実施し、特定プロセスからフォークした子プロセスの情報を取得しないので、VTuneから親プロセスの起動を実施する必要があるようです。※例: PostgreSQL等 

# 基本的な使い方

GUIの起動はWindows、プロファイリング対象はLinux(Notクラウド環境)で、Apache Cassandraをプロファイリングする場合で説明していきます。
特にApache Cassandraである必要はないですが、この手順では起動中のプロセスにアタッチすることから何らかのプロファイリング対象のプロセスをあらかじめ起動しておく必要があります。
※インストールについて特に詰まる箇所はないと思われることから省略します

## 1. VTune Profilerを起動します

起動直後の画面は次の通りです。
ここではConfigure Analysisを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/8c63c7d9-c5f6-5068-fd33-023a024985f0.png)

## 2. WHEREとしてRemote Linuxを選択します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/21d6e607-4591-57a5-8a9b-3cb986eb2ecc.png)

## 3. SSH destinationを入力しDeployを選択します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/f918a076-9f09-ff6c-6c9a-0f6eeaff681e.png)

## 4. 公開鍵を接続先のauthorized_keysのコピーします

パスワードレスでのアクセスを実現するために、次のようなウインドウが表示されるため、公開鍵を接続先のauthorized_keysにコピーします。
コピー後はこの画面上で何らかのキーを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/4c93f583-6b6e-e90d-4ea9-c0ae83f97fb5.png)

## 5. 画面が閉じた後にもう一度Deployを押します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/c2826563-82c5-d20b-7a8b-831ebbd3bcbf.png)

プロファイリング対象にソフトウェアのデプロイ完了後には次のような画面となり、警告が無くなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/ddca7fa3-fcd3-8430-4fc5-0b874a459d63.png)

## 6. WHATからAttach to Processを選択します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/e4bc8274-0c86-49f4-a154-5cbea4acf81d.png)

## 7. sample driverをインストールします

このままでもuser-mode-samplingを実施できますが、低いオーバーヘッドでプロファイリングを実施するためにこの段階でsample driverをインストールしてしまいます。

[次のドキュメント](https://www.intel.com/content/www/us/en/develop/documentation/vtune-help/top/set-up-analysis-target/linux-targets/build-install-sampling-drivers-for-linux-targets.html)を参考に、sample driverをインストールします。
なお、デフォルトではvtuneグループがインストールされたdriverにアクセスできるので必要に応じてグループに追加しておきます。

インストールディレクトリに移動し、
```
cd /tmp/vtune_profiler_2022.4.0.624343/sepdk/src/
```

次のようにビルドを実施し、

```
 ./build-driver -ni
```

最後にインストールします。
```
 ./insmod-sep -r
```

sample driverのインストールが完了したので、次に進みます。
※このまま次に進む場合、GUI上に警告が表示されたはずです

## 8. HOWからHotspotsを選択します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/9662c3cd-dd0b-a908-e16d-51c43634d36f.png)

## 9. Hardware Event-Based samplingを選択します

※この画面でCollect stacksを選択することで取得する情報が増えますが、Flamegraphや関数の呼び出し階層を取得可能となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/4ac29f7b-5505-1665-b2bd-63a7b4e88f4a.png)

## 10. 画面中央下部のStartボタンを選択します

負荷試験などを実施する場合には、この直前に起動しておくとよいと思われます。

## 11. 途中でプロファイリングを終了します

プロファイリングを開始するとこのような画面になるので、十分な情報を取得できたと判断される段階でStopを選択します。
※sampling intervalが短く、取得期間が長いほどストレージ容量が増大し、レポート作成にかかる時間が増加することに要注意です。このCassandraの例では約100秒の取得に1.6GiB程度のストレージ容量が必要でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/1d555033-ec12-b9d9-f810-d7b1c8bd27b3.png)

## 12. サマリーが表示されます

次のようにサマリーが表示されます。

CPUの利用状況やホットスポットとなっている関数/メソッドを確認できます。
※マイクロアーキテクチャの利用率がN/Aなのは、Gemini Lakeが未サポートだからだと思われます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/e6ee6626-f158-2e30-ea8b-90c3475bb09b.png)

# レポートを見てみる

?マークにマウスオーバーするだけで各用語の説明が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/caa841ff-8d19-d9b2-7525-fb6bc88b8eb3.png)

Bottom-upのページでは、名前の通りボトムアップでホットスポットとなっているモジュール/関数/メソッドなどを様々な軸で確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/eeeed0f2-066c-f42f-fd12-006d1b550515.png)

関数/メソッドをダブルクリックすることで、ソースコードがあれば行単位でどの部分がボトルネックとなっているのかを確認可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/bcb6b040-63fa-b94b-a835-00ecdb4b5ce0.png)

Caller/Calleeもその名の通り、呼び出し元/先の関係を表示可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/b5ba4730-a3eb-20f4-6365-f18c06ac89ff.png)

Top-Downのページでは、各関数/メソッドの呼び出し階層を表示できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/c0cc62ac-c1b4-7a7f-d46b-14b1c3e8064e.png)

Platformでは各スレッド、プロセスの動作状況を確認可能です。
Javaの場合には、GCの実行状況も確認できるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79343/b63d5580-c859-d18b-7268-4a9715d10c03.png)

Hotspots以外の分析についても試してみましたが、環境によっては利用できなかったり、かなり専門的であったり、あるいは仮想化環境ではそもそも利用できなかったりするので、アプリケーションのボトルネックを特定したい場合には基本的にHotspotsでよいのではないでしょうか。

スタックの情報を取得した際のflamegraphの見え方について気になる方は公式ドキュメントの[Analyzing Hot Code Paths Using Flame Graphs](https://www.intel.com/content/www/us/en/develop/documentation/vtune-cookbook/top/configuration-recipes/analyzing-hot-code-paths-using-flame-graphs.html)のページで確認できます。

# 最後に

以上のようにVTuner Profilerの簡単な使い方を見ていきました。
無料であるにもかかわらずGUIで直感的に操作でき、上手く活用すれば性能問題の原因を特定する際に非常に有益なツールであることから、使い方をマスターしたいところです。
※あまり使いこなせていない気がしますし、私の今の仕事ではたまにしか役に立ちませんが...

# リンク集

- [Analyze Performance
](https://www.intel.com/content/www/us/en/develop/documentation/vtune-help/top/analyze-performance.html)
    - Hotspots以外の利用可能な分析方法についての公式ドキュメントの説明です。
- [User Interface Reference
](https://www.intel.com/content/www/us/en/develop/documentation/vtune-help/top/reference/user-interface-reference.html)
    - 公式のユーザーインターフェースのリファレンスです。
- [Intel VTune Profiler Command Line Interface](https://www.intel.com/content/www/us/en/develop/documentation/vtune-help/top/command-line-interface.html)
    - CLI版の公式ドキュメントです。
- [Configuration Recipes](https://www.intel.com/content/www/us/en/develop/documentation/vtune-cookbook/top/configuration-recipes.html)
    - 公式の設定レシピ集です。