GC負荷軽減のためのObject削減について

お世話になっております。

現在開発してるゲームのGCの負荷軽減のためにObject数を減らそうとしてるのですがそれについていくつか質問があります。

まず、Obj Listにあるpackageについて質問です。

packageの数が26465もあるので削りたいと思っているのですが、これの中身がなんなのかを確認する方法はありますでしょうか?

次に​、Obj ListにあるFunctionの効率的な削除方法についてです。

こちらは不要な関数などが大量にあるとおもわれるのですが、なにか効率の良い削除方法はないでしょうか?

そして、現状Object数が30万近くあるのですが、「FRealtimeGC_PerformReachabilityAnalysis」を1msまで軽減させたいのですが、そのためにはざっくりと計算して15万までObject数を削る必要がありそうですが、ここまで削ると品質が落ちてしまうのでそこまで減らさずに「FRealtimeGC_PerformReachabilityAnalysis」を軽減する方法はないでしょうか?

よろしくお願い致します。

[Attachment Removed]

お世話になっております。

ご質問ありがとうございます。

> まず、Obj Listにあるpackageについて質問です。

> packageの数が26465もあるので削りたいと思っているのですが、これの中身がなんなのかを確認する方法はありますでしょうか?

数が多いためなかなか大変だと思いますが、コンソールコマンドで obj list class=package ​を実行することで、各パッケージのパスが .log ファイルに書き出されます。

> 次に​、Obj ListにあるFunctionの効率的な削除方法についてです。

> こちらは不要な関数などが大量にあるとおもわれるのですが、なにか効率の良い削除方法はないでしょうか?

​Obj List の Function には C++ ソースコード上で UFUNCTION() 指定を受けた関数も含まれます。数が多いため気になるとは思いますが、これらの関数は削減が困難なうえ、GCの回収対象でもないことから、GCの負荷軽減の観点では手を付ける必然性は高くありません。ブループリント関数については、不要なクラスやオブジェクトをロードしないという見直しの中で、結果的に削減される形が望ましいと思われます。

> そして、現状Object数が30万近くあるのですが、「FRealtimeGC_PerformReachabilityAnalysis」を1msまで軽減させたいのですが、そのためにはざっくりと計算して15万までObject数を削る必要がありそうですが、ここまで削ると品質が落ちてしまうのでそこまで減らさずに「FRealtimeGC_PerformReachabilityAnalysis」を軽減する方法はないでしょうか?

一つには、gc.AllowIncrementalReachability=1に設定することで、時間で負荷を分散するアプローチをお試しいただけるかもしれません。

また、gc.AssetClustreringEnabledなどのクラスタ設定もGCの軽量化に効果があります。デフォルトで有効化されているはずですが、念のため一度ご確認ください。

​FRealtimeGC_PerformReachabilityAnalysisの軽量化については下記のスレッドで詳しく論じられておりますので、一度ご参照いただけますと幸いです。

[Content removed]

そのほか、上記のスレッドでも論じられておりますが、「DisregardForGC」を使用して常駐するオブジェクトを明示し、Reachability解析の処理対象から外すことができます。

詳細は下記のドキュメントをご覧ください。​

https://dev.epicgames.com/community/learning/knowledge\-base/dPae/unreal\-engine\-how\-to\-register\-disregard\-for\-gc\-objects

​以上、よろしくお願いいたします。

[Attachment Removed]

お世話になっております。

gc.AllowIncrementalReachability=1

に関してですが、レベルストリーミング発生時にクラッシュしてしまい調査中に同じ問題のようなクラッシュの相談がありそちらで

「増分到達可能性解析は、単一サーバー環境でのみ検証された実験的な機能です。現時点では、通常のゲーム環境でこの機能を実用化する計画はありません。」

とのことで、使うことを断念しました。

[Content removed]

他の削減周りは参考にしてみます。

[Attachment Removed]

すみません、こちらで追加で相談させてください

DisregardForGCを試して行こうと思うのですが

こちらの対応する場合に対象のObjectに対してはCluster化は必ず必要でしょうか?

よろしくお願い致します。

[Attachment Removed]

追加ですみません

GC対象のオブジェクト数を確認する方法はありますか?

Objectを削る中でこのあたりも確認できたらと思ってます。

[Attachment Removed]

お世話になっております。

ご返信ありがとうございます。

gc.AllowIncrementalReachabilityがクラッシュを誘発し、また、Experimental度合いが強く実用にかなわないとのこと、当方で把握できておらず大変失礼しました。

余計なお手間をとらせてしまい、申し訳ございません。

> DisregardForGCを試して行こうと思うのですが

> こちらの対応する場合に対象のObjectに対してはCluster化は必ず必要でしょうか?

Cluster化は不要となります。

DisregardForGCは、エンジン/ゲームの起動シーケンスにおける特定のタイミング(FUObjectArray::CloseDisregardForGC() の呼び出し)までにロードされたオブジェクトを常駐オブジェクトとみなし、GCの追跡対象から外す仕組みです。Cluster化はこの CloseDisregardForGC() 呼び出し後でなければ作成できません。こうした機序から、 DisregardForGCの利用にあたりCluster化を検討していただく必要はない、と申し上げることができます。

詳しくは下記のドキュメントをご参照ください。

> GC対象のオブジェクト数を確認する方法はありますか?

> Objectを削る中でこのあたりも確認できたらと思ってます。

CVar gc.DumpAnalyticsToLog を 1 に設定しますと、GCの1サイクルごとに詳しいStatsがLogにダンプされます。このダンプ中の、

> LogGarbage: Pre GC: Objects: 269191, Roots : 142, Clusters : 12345, Clustered Objects : 154321

の表示を参考にしていただくのが、もっとも手軽かと思います(特に Objects: N の箇所)。

ただし、このObjects数表示には、Root Setされたオブジェクトも含まれます。Root Setされたオブジェクトは解放対象ではありませんが、Reachability解析の起点となるため、Reachability解析の負荷はこのObjects数におおむねスケールするという点で、参考になる値かと存じます。

もし実際にReachability解析でどれくらいの量のオブジェクトが走査されたかを把握なさりたい場合は、 gc.DumpAnalyticsToLog の値によらず出力される LogGarbage のログとして、

> LogGarbage: GC Reachability Analysis total time: 9.68 ms (9.68 ms on reference traversal)

> LogGarbage: 9.68 ms for GC - 269191 refs/ms while processing 2606926 references from 269191 objects with 12345 clusters

のような行があるはずですので、こちらの「 processing N references from M objects with K clusters」の M objects 部の数値を確認していただけます。

なお、これらのダンプは Shipping ビルドでは利用できないため、Development または Test ビルドでご確認ください。

以上、よろしくお願いいたします。

[Attachment Removed]

お世話になっております。

GCの負荷軽減でAddToRootを活用しようかと思うのですが

こちらは一度AddToRootしたとしてもそれを再利用するわけではなく、登録したActorをGC除外して、再度生成したときもRootに載せてるものを使うのではないという認識で宜しいでしょうか?

[Attachment Removed]

お世話になっております。

DisregardGCやcluster化を活用して

ゲーム中のGC対象のObjectを「obj list -GCNOCLUSTERS」でGC対象を調べたところ

15万ほどまで減らせました。

それでもFRealtimeGC_PerformReachabilityAnalysis (7.2 ms)と検索に時間がかかってるようなのですが

まだObject数的には多い方でしょうか?

[Attachment Removed]

お世話になっております。

> GCの負荷軽減でAddToRootを活用しようかと思うのですが

> こちらは一度AddToRootしたとしてもそれを再利用するわけではなく、登録したActorをGC除外して、再度生成したときもRootに載せてるものを使うのではないという認識で宜しいでしょうか?

​こちらはご認識のとおりでございます。

AddToRootは適用したアクタ(オブジェクト)をスウィープの対象から外すことができますが、アクタ(オブジェクト)単位での適用となります。また、その効果はあくまで解放の対象にならない(UEのスマートポインタでどこからも参照されていなくても、解放の対象とならない)だけで、Placement New相当の処理が実行されてメモリ領域が再利用される・・・という仕組みとは根本的に異なります。

そのため、そのクラスで新しいアクタ(オブジェクト)をNewした場合は、Root Setされていないものが作成され、通常通りスウィープの対象となります。

また、AddToRootされたオブジェクトはReachability解析の起点として利用されるため、引き続き解析には絡む存在であり、解析負荷を積極的に下げる働きを持たない点にご注意ください。

Reachability解析の負荷を下げるには、オブジェクトの総数が減少することが有効で、スウィープも含めたGC全体の負荷を下げるには、オブジェ クトの作成と破棄の総数が減ることが有効です。そのため、一般にオブジェクトのプールシステムを組むことが効果的となります。

以上、よろしくお願いいたします。​

※本回答を入力中、ちょうど入れ違いで新しいご質問を頂戴したようです。

こちら回答まで少々お時間を頂戴できれば幸いです!

[Attachment Removed]

ご返答ありがとうございます。

こちらも、再度リファレンスを確認したところGCへの良い影響はなさそうと再確認できました。

ほかの方法がないか探ってみます。

[Attachment Removed]

お世話になっております。

お待たせいたしました。

結論から申しますと、NoClustersでのObject数15万、Reachability解析7.2msは、弊社のプロジェクトと比較しても妥当な範囲であり、社内のUEコアシステム関係のエンジニアの所感としても「7.2msは相当高速」の類いに入るとのことでした。

当初お話しいただいた「1ms」という目標値は、実のところ社内外で目にしたことのない水準の数値であり、残念ながら今日の一般的な市販ゲームがもつ物量では到達しえない数値であると申し上げざるを得ないかもしれません。

そのため、まだパフォーマンス不足が生じているのであれば、他のパートで最適化を進めていただくのがお勧めとなります。

仮に引き続きGC周りの最適化をはかるのであれば、参照構造を見直し(クラスター化や無駄な参照の除去)つつ、GC稼働のタイミングを調整する、という取り組みになるかと思います。

・低レベルプロファイリングを行い、ボトルネックを特定する(UObject::AddReferencedObjectsのカスタム実装や、スレッドスケジューリングなど)

・Reachability解析の走査対象をダンプするコードを書き、情報をもとに、さらなるクラスター化の推進や、不要な参照の除去を行う(たとえば、他のオブジェクト経由でアクセス可能なオブジェクトを大量にキャッシュしているクラスやプロパティがある場合、それを弱参照に切り替えるなど)

・必要以上にGCを稼働させないよう、タイミングをずらす(メモリに余裕があれば、プレイヤーがGC稼働を体感しづらい状況までディレイさせるなど)

以上、よろしくお願いします。

[Attachment Removed]

ありがとうございます。

Reachability解析7.2msは高速なのですね。

こちらの情報を共有して他の箇所でパフォーマンス出すように対応してみます。

[Attachment Removed]

ご返信ありがとうございます。

それでは案件管理の都合上、本件は回答済みとして、元トピック(“GC負荷軽減のためのObject削減について”)についてはCloseさせていただこうかと考えておりますが、他に何か関連したご質問などございますでしょうか?

ご確認のほどよろしくお願いいたします。

[Attachment Removed]

はい、こちらはクローズで問題ありません。

細かいことはプライベートな方でご相談させて貰えればと思います。

[Attachment Removed]

ありがとうございます。

それではこちらはクローズとさせていただきます。

引き続きよろしくお願いいたします。

[Attachment Removed]