Skip to main content
IOStore
Epic Games Japan
Software Engineer, Developer Relations
Ken Kuwano
#UE4 | @UNREALENGINE
はじめに
● IOStoreはまだ実験的な機能のため、構成や詳細な内容は今後
変わる可能性があります
● 内容は UE4.25.4 をベースとした内容となります
#UE4 | @UNREALENGINE
目次
● IOStoreの概要
● IOStoreとNewLoader
● ロードと負荷対策
#UE4 | @UNREALENGINE
IOStoreとは
● UE4.25から実装された新しいロードシステムの一部
● IOの情報をストア(保管)する機能
● IOのパフォーマンスを改善してロードを高速化
● IOStoreの機能を有効にしたパッケージアプリで有効
#UE4 | @UNREALENGINE
ロードシステムのロードマップ
AsyncLoader
従来のローダー
AsyncLoader2
新しいローダー
Editor動作
Not IoStoreビルド
IoStoreビルド
UE4.25
Experimental
UE4.26
Beta
#UE4 | @UNREALENGINE
AsyncLoader2とは?
フォーラム:Unreal Engine 4.26 Previewより抜粋
#UE4 | @UNREALENGINE
Build
 Cook
 Stage
 Package

IOStoreの作用
Archive

.uasset .uasset
.uasset .uasset
.pak
暗号化や圧縮のために
1つのファイルにまとめる
パッケージ作成フロー (IOStore=OFF)
#UE4 | @UNREALENGINE
Build
 Cook
 Stage
 Package

IOStoreの作用
Archive

.uasset .uasset
.uasset .uasset
.pak .utoc
.ucas
アセット
+高速化用のファイル
パッケージ作成フロー (IOStore=ON)
#UE4 | @UNREALENGINE
IOStoreの適用
IOStoreを有効にしたアプリケーションパッケージを作成
[手順]
1. IOStoreを有効にする
2. パッケージを作成する
#UE4 | @UNREALENGINE
IOStoreの有効化
以下のいずれかの方法でIOStoreを有効にしたパッケージを作成できる
● Project設定でUsePakFile, UseIoStoreを有効にする
● Project LauncherではUnrealPakとI/OStoreを有効にする
● UATの”BuildCookRun”実行時は”-iostore”, “-pak”の両方を指定
#UE4 | @UNREALENGINE
IoStore=OFF
IoStore=ON
パッケージ作成後のアセット配置の違い
#UE4 | @UNREALENGINE
.pakファイル以外に.ucas, .utocファイルが追加
IOStore有効時のファイル構成
.pak : パックファイル
.ucas : コンテナファイル
.utoc : 目次ファイル
#UE4 | @UNREALENGINE
.pak:パックファイル
● IOStore=OFF時は 全てのアセットファイル を格納
● IOStore=ON時は アクセス頻度が低いファイル を格納
● .ini, .ushaderbytecode, .uproject などが保存される
● 今まで保存されていたアセットファイルは.ucasに移行
#UE4 | @UNREALENGINE
アセットファイル (.uasset, .umap, .ubulk, .uptnl, uexp)を格納
● 16Byteアライメントオーダーによるパフォーマンス向上
● アセットデータの効率的な配置によるファイルアクセスの高速化
.ucas:コンテナファイル
アセット1 00 00
0 15
アセット2
アセット2 00 00 00 00
アセット3 00 00 00 00 00 00
アセット3
アセット情報
(FIoBuffer)
#UE4 | @UNREALENGINE
目次(TOC:Table Of Contents)情報を格納
● .ucasとパッケージを紐づけるため目次情報
.utoc:目次ファイル
ChunkId OffsetAndLength
ヘッダー情報
(FIoStoreTocHeader)
アセット別情報
(FIoStoreTocEntry)
Magic Header Size Entry Count Entry Size Padding
1001 0 320
1002 320 160
1003 480 32000
#UE4 | @UNREALENGINE
プロジェクトとは別にグローバル.ucas/.utocファイルが追加
IOStore有効時のファイル構成
#UE4 | @UNREALENGINE
global.ucas:グローバルコンテナファイル
コンテナからパッケージをロードするために必要な情報が格納
IoChunkType 内容
LoaderGlobalMeta グローバルメタ情報テーブル
パッケージのロードに関するストア情報
LoaderInitialLoadMeta 初回ロードメタ情報テーブル
パッケージとバンドルを紐づける情報
LoaderGlobalNames グローバルネームテーブル
ロード時にバンドルとオブジェクト名を紐づけるネームテーブル
LoaderGlobalNameHashes グローバルネームハッシュ
ロード時にバンドルとオブジェクト名を紐づけるハッシュテーブル
#UE4 | @UNREALENGINE
global.utoc:グローバル目次ファイル
こちらは空のヘッダー情報のみで未使用
#UE4 | @UNREALENGINE
IOStoreの効果検証
条件
● サンプルでスタートアップレベルのロード時間を計測
● Win64/Testビルドのパッケージ, Unreal Insightsを使用
※KiteDemoはWorldComposition無効で計測
#UE4 | @UNREALENGINE
サンプルでの検証結果
IOStoreの有効化はロード時間を改善
28%↓
28%↓
5%↓
#UE4 | @UNREALENGINE
目次
● IOStoreの概要
● IOStoreとNewLoader
● ロードと負荷対策
#UE4 | @UNREALENGINE
Game
アセットロード時の非同期ロードってこんなイメージだっけ?
Async Loading Load
Other Work
アセット
Data
Request
Read
「非同期ロードはGameに影響しない」ではない。
(正しくは次ページ以降で)
#UE4 | @UNREALENGINE
GameThread
AsyncLoaderによるロードの概念図
AsyncLoading
Thread
PoolThread
Load
Work/Wait
Work/Wait Complete
Complete
Seek/Read
Read
.pak
Data
ゲームのメイン処理
バックグラウンドのロードを制御
ファイルの読み込み制御
Load
Request
#UE4 | @UNREALENGINE
LoadPackage
AsyncArchivePoolThread
Seek/Read
GameThread
AsyncLoading
Thread
Event
Queue
AsyncLoaderによるロードとファイルアクセス
AsyncPackage
CreateLinker
Start
QueuePackage
AsyncPackage
AsyncPackage
AsyncPackage
スレッド
#UE4 | @UNREALENGINE
AsyncLoaderによるロードとファイルアクセス
AsyncArchivePoolThread
⑤ Seek/Read
GameThread
AsyncLoading
Thread
Event
Queue
AsyncPackage
③ CreateLinker
④ Start
② QueuePackage
AsyncPackage
AsyncPackage
AsyncPackage
① LoadPackage
スレッド
#UE4 | @UNREALENGINE
AsyncLoader
● Async Loading Thread
● Game Threadのバックグラウンドでアセットをロード
● Pool Thread
● FileIOのAPIを実行して.pakファイルからアセットを読み込み
#UE4 | @UNREALENGINE
Game Thread
AsyncLoader2によるロードの概念図
Async Loading
Thread2
IoService
Load
Work/Wait
Work/Wait Complete
Complete
Seek/Read
Read
.ucas
Data
ゲームのメイン処理
バックグラウンドのロードを制御
ファイルの読み込み制御
Load
Request
#UE4 | @UNREALENGINE
AsyncLoader2によるロードとファイルアクセス
LoadPackage
IoDispatcherIoService
Seek/Read
GameThread
AsyncLoading
Thread2
Event
Queue
AsyncPackage2
ReadWithCallback
ReadFrom
BlockFile
QueuePackage
AsyncPackage2
AsyncPackage2
AsyncPackage2
スレッド
#UE4 | @UNREALENGINE
AsyncLoader2によるロードとファイルアクセス
① LoadPackage
IoDispatcherIoService
⑤ Seek/Read
GameThread
AsyncLoading
Thread2
Event
Queue
AsyncPackage2
③ ReadWithCallback
④ ReadFrom
BlockFile
② QueuePackage
AsyncPackage2
AsyncPackage2
AsyncPackage2
スレッド
#UE4 | @UNREALENGINE
AsyncLoader2
● Async Loading Thread2
● 新しい非同期ロード用スレッド
● IOStoreを利用するための変更
● CPUオーバーヘッドを減らし効率的な方法でIOをリクエスト
● IoDispatcher
● Async Loading ThreadとIoServiceを中継
● IoService
● FileIOのAPIを実行して.ucasファイルからアセットを読み込み
#UE4 | @UNREALENGINE
目次
● IOStoreの概要
● IOStoreとNewLoader
● ロードと負荷対策
#UE4 | @UNREALENGINE
https://www.slideshare.net/EpicGamesJapan/ue4loadinggcprofiling
このスライドを見れば分かりますが、
#UE4 | @UNREALENGINE
Unreal Insightsでロードの解析と改善策の検討もできます
#UE4 | @UNREALENGINE
スレッドの処理やアセット毎の処理時間を視覚化
(Asset Loading Insights)
#UE4 | @UNREALENGINE
#UE4 | @UNREALENGINE
AsyncLoader2によるロードとファイルアクセス
LoadPackage
IoDispatcherIoService
Seek/Read
GameThread
AsyncLoading
Thread2
Event
Queue
AsyncPackage2
ReadWithCallback
ReadFrom
BlockFile
QueuePackage
AsyncPackage2
AsyncPackage2
AsyncPackage2
スレッド
#UE4 | @UNREALENGINE
有効にする
#UE4 | @UNREALENGINE
プロファイルをキャプチャ
以下の起動引数を追加してアプリケーションを起動
-trace=cpu,file,loadtime -statnamedevents -AsyncLoadingThread
#UE4 | @UNREALENGINE
ロードの検証ポイント
どこで処理に時間が掛かっているか (バーが長い?)
● IO
● Async Loading Thread
● Game Thread
#UE4 | @UNREALENGINE
アセットロード時のタイムライン (フロー)
#UE4 | @UNREALENGINE
AsyncLoader2によるロードとファイルアクセス
LoadPackage
IoDispatcherIoService
Seek/Read
GameThread
AsyncLoading
Thread2
Event
Queue
AsyncPackage2
ReadWithCallback
ReadFrom
BlockFile
QueuePackage
AsyncPackage2
AsyncPackage2
AsyncPackage2
スレッド
#UE4 | @UNREALENGINE
アセットロード時のタイムライン (フロー)
#UE4 | @UNREALENGINE
アセットロード時のタイムライン (フロー)
①
②
③
④
⑥
⑤
#UE4 | @UNREALENGINE
アセットロード時のタイムライン (ポイント)
IO
AsyncLoading
Game
#UE4 | @UNREALENGINE
アセットロード時のタイムライン (IO)
IO
#UE4 | @UNREALENGINE
負荷要因と対策 (IO)
負荷
● ファイルの読み込み時のシークとリード
対策
● アセットのデータサイズ削減
● アセットの読み込みタイミング変更 (常駐化、先読み、後読み)
#UE4 | @UNREALENGINE
アセットロード時のタイムライン (AsyncLoading)
AsyncLoading
#UE4 | @UNREALENGINE
負荷要因と対策 (AsyncLoading)
負荷
● パッケージのリファレンス
● ネイティブクラスのコンストラクタ
● シリアライズ処理(テクスチャ, マテリアル, スタティックメッシュなど...)
対策
● リファレンス(ハード/ソフト)の管理
● コンストラクタ処理の最適化
● テクスチャ(Shadowmap, Cubemap, Lightmap)の解像度、Mip設定の見直し
● シェーダーが参照するリソース数の削減
● スタティックメッシュのLOD設定の削減
#UE4 | @UNREALENGINE
アセットロード時のタイムライン (Game)
Game
#UE4 | @UNREALENGINE
負荷要因と対策 (Game)
負荷
● レベルストリーミング
● アクター、コンポーネントの追加
● アニメーション処理、物理ボディのセットアップ処理
● マテリアルのポストロード処理
対策
● レベルストリーミングのタイミング調整
● 余剰なアクター、コンポーネントの整理
● アニメーションの制御、Collision設定, 物理ボディ数の調整
● 不要なマテリアルのロードチェック
#UE4 | @UNREALENGINE
ロードの検証ポイント
どこで処理に時間が掛かっているか (バーが長い?)
● IO
● Async Loading Thread
● Game Thread
#UE4 | @UNREALENGINE
まとめ
● IOStoreを利用することでロード時間の短縮
● 4.25ではExperimental, 4.26ではBetaとして利用可能
● IOのパフォーマンスとCPUのオーバーヘッドを抑制
● ロード時間は積極的に改善
● Unreal Insightsは解析の役に立ちます
● 実装の時点から注意しておきましょう
#UE4 | @UNREALENGINE