お世話になっております。
UE5.8からStreamableManagerにJIT AsyncLoadingという割り込みロードのような機能が追加されたので、これに便乗して少し質問させてください。
まず先に、JIT AsyncLoadingの機能について、
StreamableManagerのリクエストの粒度をコントロールすることでプライオリティによる割り込みができるようになった、という理解で間違っていませんでしょうか?
つまり、
- StreamableManagerを使用して大量のアセットのロード発行している場合は有効に動くが、AsyncLoading内でアセット参照に紐づく追加のロードが行われる部分には関与しない
- レベルなど大量のアセットが紐づいているものをStreamableManagerで単品ロードした場合は動作しないので、AssetRegistryなどを使用して依存アセットを抜きだしてからStreamableManagerでロードを発行する必要がある
こちらの理解が正しければ、エンジンのロードでは直接AsyncLoadingを使用しているものが多く、今回のJIT AsyncLoadingのメリットが少ないと感じています。
将来的にエンジン側もStreamableManagerを使用したロードに置き換えられていくのでしょうか?
また、StreamableManagerに抽出したアセットリストを渡す場合、アプリ側にせよエンジン側にせよ依存するアセットリストを抽出が必要になりますが、依存アセットのファイル数が1000オーダーを超えてくると抽出処理がカクツキの原因となるため別スレッドでの処理が必要になります。
今まではこの部分はAsyncLoadingThjread内で行われていたので気楽にロードリクエストを発行していましたが、JIT AsyncLoadingをうまく動作させるにはこの部分も何かしらフォローするような機能が必要になってきそうです。しかもAssetRegistryはパッケージに含めないこともできるので、ランタイムで依存アセットを先に抽出するということが無理なケースもありそうです。
ここで質問なのですが、
- JIT AsyncLoadingをうまく使用するにはどういったシナリオが想定されていますか?
- また、根本的な解決のためのAsyncLoading内での割り込みロードの実装は行われないのでしょうか?
自分がAsyncLoadingに割り込みロードが欲しいと思っている具体的なシナリオは以下のようなケースです
- レベルストリーミングやWPのセルのロードで裏読みを行う
- この状態でゲーム進行に伴いさらに別のアセットが必要になった時に優先的にロードを行いたい
よろしくお願いいたします。
[Attachment Removed]
お世話になっております。
少しテストしたところ、AsyncLoading2の割り込みロードは実装されていました。
ZenLoaderができたころはプライオリティはI/O優先度にしか影響していなかったと思うのですが、UE5.2からEDLの直列のイベントリストがTIoPriorityQueueによるプライオリティ付きのリスト管理になったようで、EDLの処理もプライオリティを考慮した処理順になるように変わっていました。
これで、何かのロード中に他のロードリクエストを投げてもロードが先に終わればPostLoadおよびCompletedが先に呼び出されるようになっていたので、自分の望んでいた割り込みロード処理自体は完成していそうです。
テスト不足で質問して申し訳ありませんでした。StreamableManagerの件だけ回答お願いいたします。
[Attachment Removed]
お世話になっております。
JITAsyncLoadingはFStreamableManagerに実装されている機能で、以下のような仕組みです。
機能概要と背景
- 通常は非同期ロードリクエストをまとめてキューに投げますが、JIT方式では1つのハンドルに対するリクエストを少しずつAsyncLoadingThread(ALT)上でキューに追加していきます
- これにより、リクエストの完了を待つタイミングで優先度の再設定や、まだキューに入っていないリクエストの実質的な「キャンセル」ができるようになります
- ご認識のとおり、ALT自体はキャンセル機能をサポートしていないため「キャンセルする代わりに、そもそもロード量を減らす」というアプローチとして JIT が採用されました
- 弊社コンテンツの利用方法として、優先度の動的な更新に使われており、ゲームスレッドの完了コールバックで優先度を更新し、以降のリクエストはその新しい優先度でALTにキューされます
- 今後JITがALTに置き換わるかということについては、現時点で置き換わることはありません
- また、同様にALT/ALT2本体にキャンセルが入るということは計画しておりません
注意事項
- ご認識のとおり、StreamableManager で 大量の対象を列挙して順に発行するようなケースで有用ですが、1パッケージを キックしたあとのインポート展開(ALT内部の追加ロード)には関与しません
- そのため、レベルやWPセルを単品で渡しても、その巨大な依存グラフは ZenLoader が summary から一気に引っ張り、JIT の対象外になります
ALT2へのご理解
- キュー済み、未開始の作業を優先度で並べ替える仕組みは既にALT2にあり、現行のZenLoaderはI/O Priorityだけでなく、EDL の"次に実行するイベント"も TIoPriorityQueue で選びます
- 低優先の裏読みがキューに乗っている状態で高優先の LoadPackageAsync を出すと、未実行のEDLイベントを追い越してロードを優先実行します
つまり「裏で WP セルを読んでいる最中に、ゲーム進行用アセットを先に読みたい」ようなケースに対しては、JITではなく LoadPackageAsync の優先度で対処するのがエンジンのデフォルト機能を活用する方法であり、ゲーム側を AsyncLoadHighPriority(100)等で出せば、まだ始まっていない import 群より先に拾われやすくなるはずです。
[Attachment Removed]
お世話になっております。
AsyncLoading2の割り込みロードについて、改めてまとめていただきありがとうございます。
動作確認もできていますのでこれからはプライオリティ制御でうまくコントロールしていけそうです。
StreamableManagerのJIT AsyncLoadingについても、詳細な解説ありがとうございます。
アセット参照を展開せずにリクエストのアセットの粒度がまちまちな状態でも、優先度で前後関係を変えられるので変えられるのでそれほど問題にならないということですね。
キャンセルなども含めていいバランスで使用できるように考えてみます。
情報ありがとうございました。
# 先日のDevDayのZenシリーズの解説もありがとうございました!とてもわかりやすくて理解が深まりました。
[Attachment Removed]
ご確認頂きありがとうございました。
実現されたい内容の方向性を確定させるための情報がお伝えできてよかったです。
また、DevDayについてもセッションにご参加いただきありがとうございました。Zenのような分かりにくい部分を今後もお届けできればと思いますので引き続きよろしくお願いします!
[Attachment Removed]