■ 1. VALORANTの128tickサーバー実現の背景
- 厳格な要件: 開発初期からVALORANTには非常に厳格なサーバーパフォーマンス要件があった
- 初期状態と目標: 開始時はサーバーフレームが50msかかっていたが、最終的にフレームあたり2ms未満を達成した
- 最適化手法: コード最適化、ハードウェアの調整、OS チューニングを組み合わせて目標を達成した
- ピーカーズアドバンテージ: すべてのオンラインシューターにはピーカーズアドバンテージが存在し、VALORANTでは戦略的ポジションの維持が重要なゲームプレイ要素である
- レイテンシの構成: レイテンシはネットワークとサーバーのtickレートに部分的に基づいており、ディフェンダーが反応する時間を確保するため128tickサーバーが必要と判断した
■ 2. CPU リソースの制約と目標設定
- 基本制約: 128tickレートでサーバーをホストする際の最大の制約はCPUリソースである
- フレーム処理時間: 7.8125ms以内に1フレーム全体を処理する必要があるが、そのままでは1ゲームが1つのCPUコア全体を占有してしまう
- コスト削減の必要性: 128tickを無料で提供したいため、コアあたり3ゲーム(gpc)以上の効率が必要だった
- スケールの規模: 36コアのホストを一般的に使用し、各物理ゲームサーバーは108ゲームまたは1080プレイヤーをホストする必要があった
- 最終目標: オーバーヘッド10%を考慮すると、フレームあたりわずか2.34msという目標予算となった
■ 3. 問題の分解とテレメトリーシステム
- アプローチ: 「サーバーを20倍高速化する」という大きな問題を小さな解決可能な問題に分解した
- カテゴリー分類: replication、FoW、network、animation、gameplay、movement、equippable、character、physics、otherの10カテゴリーに分類した
- ValSubsystemTelemetry: プログラマーが簡単にゲームコードをマークアップして適切に分類できるシステムを構築した
- マクロシステム: 実行されるすべてのコード行がマクロシステムを使用して上記のバケットの1つにスコープされる
- サブシステム概念: より大きなシステムの詳細な分析のためにサブシステムの概念を追加した
■ 4. Analytics Platformの活用
- Riotの技術活用: Riotの中央チームが開発したAnalytics Platformを活用してデータをビッグデータウェアハウスに公開し視覚化を構築した
- 視覚化の種類: ラウンドごとの平均サーバーフレーム時間、各VALサブシステムの平均処理時間などを視覚化した
- 早期発見: このようなデータがなければ、パフォーマンスの低いコードやコンテンツの変更が検出されずにゲームに入り込む可能性がある
- 問題特定の効率化: 変更番号間でレプリケーションが長くなった問題など、より小さな変更セットを調べて迅速にエンジニアを割り当てることができる
■ 5. サブシステムごとのパフォーマンス予算
- 予算設定: 視覚化が設定されたことで各サブシステムに予算を設定し不一致をフォローアップできるようになった
- 専門家による判断: VALORANTの技術リードが集まり、各システムの妥当な予算について議論した
- 最適化機会の評価: 予算は当時のシステムの状態と専門家による最適化の機会に基づいて決定された
- 並行作業: 各チームと専門家が目標を念頭に置き、並行してパフォーマンスを出荷可能な状態にすることができた
■ 6. Replicationシステムの最適化
- システムの役割: Property Replicationはサーバーとクライアント間の状態のネットワーク同期を可能にするUnreal Engine 4のシステムである
- パフォーマンスの問題: 変数を「replicated」としてマークするだけで自動的に同期されるが、メモリ全体でランダムアクセスが発生しキャッシュ集約的で遅い処理となる
- ポーリングの問題: 状態変更に関係なく変数がチェックされるポーリングシステムはパフォーマンスのアンチパターンである
- RPCによる解決: Remote Procedure Calls(RPC)を利用することで状態変更イベント時のみパフォーマンスコストが発生する「プッシュ」モデルを実現した
- 劇的な改善: replicatedな変数からRPCへの変更により、多くの場合100倍から10000倍のパフォーマンス改善が得られた
■ 7. Animationシステムの最適化
- サーバー側のコスト: ショットが当たったかどうかを適切に判断するため、サーバー側でもクライアントと同じアニメーションを実行する必要があった
- ヒット判定の仕組み: 履歴バッファーにプレイヤーの位置とアニメーション状態を保存し、ショットパケット受信時に巻き戻して計算する
- フレーム間隔の調整: 当初は毎フレームアニメーションを計算していたが、4フレームごとにアニメーションを実行し、巻き戻し時には保存されたアニメーション間を補間することで75%のコスト削減を実現した
- バイフェーズの最適化: バイフェーズ中はプレイヤーが安全にスポーンバリアの後ろにいるため、サーバー側のアニメーションを完全にオフにすることでラウンド全体のアニメーションシステムコストをさらに33%削減した
■ 8. 負荷テストとCPUアーキテクチャ
- 負荷テストの必要性: 実世界でゲームがどのように機能するかを適切にテストするため、100以上のインスタンスが同じCPU上で実行される負荷テストを構築した
- パフォーマンスの劣化: 単一インスタンス実行時は1.5msだったが、168インスタンス実行時には5.7msまで上昇した
- キャッシュの競合: 各コアには独自のL1/L2キャッシュがあるが、より大きなL3キャッシュはコア間で共有されるため、インスタンスが増えるとキャッシュの競合が発生する
- Intelとの協力: Intel Xeon E5プロセッサーからIntel Xeon Scalableプロセッサーへの移行により、非包括的キャッシュを採用し約30%のパフォーマンス向上を実現した
■ 9. NUMAとOSスケジューラの最適化
- NUMA アーキテクチャ: デュアルソケットCPUでは各ソケットがシステムRAMの一部に直接アクセスし、インターコネクトを通じてデータを共有する
- numactl の活用: Linuxのnumactlを使用してゲームサーバーインスタンスをノード間で交互に起動することで、約5%のパフォーマンス向上を実現した
- メモリアクセスの改善: メモリアクセスを約50%のNUMAローカルから97-99%のNUMAローカルに向上させた
- スケジューラの調査: コアが90-96%の使用率で推移し100%に達しない問題をLinuxのCompletely Fair Scheduler(CFS)が原因と特定した
- マイグレーションコスト: デフォルト値0.5msをゼロに下げることで、スケジューラーがゲームサーバーを利用可能なコアに即座にマイグレートするようになり4%のパフォーマンス向上を実現した
■ 10. C-Statesとハイパースレッディング
- C-State の制御: プロセスを高いC-State(C0、C1、C1E)に制限することで、さらに1-3%のゲームを安定してホストできるようになった
- 電力状態の影響: 負荷が減少すると多くのコアが頻繁にアイドル状態になり、電力状態のスワップがパフォーマンスに悪影響を与えていた
- ハイパースレッディングの検証: 開発初期は25msのフレーム時間でハイパースレッディングをオフにすると20msになり25%向上したが、最適化後は逆にオンにすることで25%向上した
- 変化する最適解: フレーム時間を7.8125ms以下に削減し、Intel Xeon Scalableプロセッサーへの移行、スケジューラーの調整、C-Stateの無効化などにより最適な設定が変化した
- 測定の重要性: 各アプリケーションのパフォーマンスプロファイルと考慮事項は異なり、再現可能なテストを作成して測定することが唯一の確実な方法である
■ 11. その他の最適化と本番環境固有の問題
- Clocksource の最適化: XenクロックソースからCPU命令rdtstを使用するtscクロックソースに変更することで1-3%のパフォーマンス向上を実現した
- Mesos とTelegraf の問題: 本番環境のみで発生する問題として、Mesosが使用するTelegrafのメトリクスが5秒ごとに72個のプロセスを起動しゲームサーバーをコアから追い出していた
- Erlang スケジューラの設定: Erlangのスケジューラースレッド数をデフォルトの72(コアごとに1つ)から4に設定することで問題が解消した
- 本番環境での測定: 本番環境に一致する構成でパフォーマンスを測定することが極めて重要である
■ 12. 結論と成果
- 全体目標の維持: 技術的な細部に迷わず、念頭に置いている全体的なパフォーマンス目標を継続的に再検討し強化する必要がある
- チームの調整: 適切なタイミングで適切な支援を得られるよう、チーム全体を目標に向けて調整することが重要である
- 環境の最適化: コード最適化は大きな部分を占めるが、ハードウェアとOSの環境も最適化する必要がある
- 測定の徹底: VALORANTの測定により、サーバーハードウェアのニーズを1%以内で予測しながらローンチすることができた
- 最終成果: スムーズなローンチ体験とプレイヤーへの無料128tickサーバーの提供を実現した