ハイパフォーマンスなコア部分の開発手法〜プロファイル駆動開発のススメ〜
トライエースによるCEDEC 2020での講演.
http://research.tri-ace.com/
プロファイル駆動開発
似た用語にベンチマーク駆動開発
テスト駆動開発のリファクタリングのフェーズを「プロファイル」「最適化」に分割する.
保守性が高い.
CIでPDDサイクルを回す.
プロファイル用のコードの保守
リビジョンで比較して劣化をアラートできる.
生産性が高い.
ゲームの構成要素
クライアントには自動プロファイリング
サーバには継続的な負荷試験
PDDサイクル
PDDサイクルはDailyで回される.
サーバがCIで自動プロファイリング
結果がダッシュボードやSlackに通知される.
ダッシュボード
MySQLとMetabaseを利用.
Metabaseはドリルダウンがあまりよくない.
FilterBoxを利用する.
Android向けUnity製ゲーム最適化のためのCI/CDと連携した自動プロファイリングシステム
SlackアプリでUXにこだわって通知.
継続的な負荷試験
PDDサイクルは深夜帯にCIで行う.
システム全体の監視.
コネクション関連など.
継続的な負荷試験はパフォーマンスの測定が目的であり,限界を知ることではない.
リリース前の負荷試験とは異なる目的.
QAや企画のプレイから取得されるRPCログから自動でシナリオを生成.
MUNIN
C++でコア部分の実装を全て行い,共通化する.
開発環境をシームレスに.
最適化の恩恵が広く影響する.
ユニットプロファイリングでPDDサイクルを回す.
ユニットプロファイリング
従来
実装コードの開始と終了に関数を仕込んで測定
実際の入力データを利用
デメリット
実装コードが汚れる.
コストが大きい.
関数の呼び出しなどは自動プロファイリングでだいたいわかる.
Slow Function Ranking
ユニットプロファイリング
単体テストのプロファイル版.
単体テストの使用感で利用できる.
自動で実行される.
Google Benchmark: C++
BenchmarkDotNet: C#
JSONで出力してSlackアプリなどで利用.
MetabaseのPulseを利用しているが,まだ発展途上.
独自実装に変更予定.
コンソールでも確認ができる.
高精度なベンチマーク
IntelのWhite Paperが大変参考になる.
RDTSCを利用する.
Linuxカーネルで実装すれば割込みやプリエンプションを無効化できる.
OoOの無効化
統計的アプローチ
全体の何度も繰り返して平滑化する.
サーマルスロットリングの問題
計測時間外に適度にスリープ
サーキュレータで冷却
その他できることいろいろ
無関係なプロセスの停止.
スレッドプライオリティ
実行するCPUを指定.
初期化後に少しだけスリープ
アプリ開始時にパフォーマンスが安定するまで実行しない.
Google Benchmarkの検証
結果の出力や精度に課題.
機能の多様性に強さ.
Mathライブラリ
当初は速かったライブラリも今は遅い.
HLSLとのinterfaceの共通化など.
OSSの調査
DirectXMath
速そうだけどinterfaceが微妙.
GLM
interfaceが良いが早いか微妙.
Mathライブラリ開発
テストを書きながらOSSやMathライブラリをプロファイル
新Mathライブラリを実装.
PDDサイクルでパフォーマンス改善.
コンパイラの気持ちを考えてSIMDで動くように書く.
逆アセンブルで結果確認.
プロファイル -> 逆アセンブル -> 最適化
最適化
SIMDで動くVectorクラスを作成し,MatrixではVectorを利用.
C++17以降を使いましょう
if constexprが強力
デバッグビルドでも気を抜かずに最適化
ユニットプロファイリングの結果が良くても,ゲーム全体が速くなるとは限らない.
包括的にPDDを整えることが大切.
パフォーマンス監視
総合監視環境
ビルド,デプロイ結果.
単体テスト,回帰テスト,画像回帰テスト
プロファイリング系