2K Views
November 18, 17
スライド概要
2017/11/18に開催されたUnity道場スペシャル 2017京都の講演スライドです。
講師:黒河 優介(ユニティ・テクノロジーズ・ジャパン合同会社)
「効果的な最適化のために事前に何をしたらよいか?」「どういう考えで最適化を行っていけばよいか?」などの基本的な考え方から、具体的なProfilerの使い方までお伝えしていきたいと思います。この講演で紹介する考え方は、日本のエンタープライズチームを通して得た知見になります。最適化のテクニックそのものは紹介しませんが、考え方を身につける事で、最適化のために役立つでしょう。
こんな人におすすめ
・最適化したいが、何をしてよいかわからず困っている人
・効率的に最適化を行いたい人
受講者が得られる知見
・Unity Profilerに関するノウハウ
・最適化の目算、見積もりをする技術
Unityのイベント資料はこちらから:
https://www.slideshare.net/UnityTechnologiesJapan/clipboards
リアルタイム3Dコンテンツを制作・運用するための世界的にリードするプラットフォームである「Unity」の日本国内における販売、サポート、コミュニティ活動、研究開発、教育支援を行っています。ゲーム開発者からアーティスト、建築家、自動車デザイナー、映画製作者など、さまざまなクリエイターがUnityを使い想像力を発揮しています。
最適化をする前に覚えておきたい技術 - Unity道場 京都スペシャル2 Edition ユニティ・テクノロジーズ・ジャパン合同会社 エンタープライズサポート 黒河 優介
自己紹介 • 役職 • ユニティ・テクノロジーズ・ジャパン合同会 エンタープライズコンサルティングデベロッパー リレーションマネージャー/エンジニア • 仕事内容 • 大規模プロジェクトのサポート業務 • プロジェクトに合う形で、パフォーマンスに関す る提案等を行っている
この講演について 本講演はUnite2017の「最適化をする前に覚えておきたい技術」を ベースに作成しております。
本日の講演内容 • 「最適化」とは何なのか? • 「プロファイリング」について • 実際のケーススタディ • ステップアップのためのTIPS
本日の講演 • 講演資料のキーとなる箇所には ユニティちゃんが出現 大事なポイント やってはダメなパターン 覚えておくと役立つ知識
最適化とは何か? • スクリプト、プロジェクトの設定、シーンの構成を見直して、ゲームの クオリティを維持したまま、パフォーマンスの向上・メモリの削減を行 う事
なぜ最適化を行うのか? • ターゲットにしている端末で、想定している処理速度が出ない • これによりユーザー体験が落ちてしまう • ユーザー体験が落ちたことによる低評価を避けたい ターゲットにしている端末で十分快適に遊べているなら、無理して最適化 を行う必要はない
最適化とは? より良いゲーム体験のため、 プロジェクトを見直して、適切な形に 組みなおす事
最適化を行いたいシチュエーション • メモリ使用量が多くて、ゲームが不正終了してしまう • ロード時間が長くて、ゲームのテンポが悪くなってしまう • ゲームプレイ中に急に画面が一瞬固まり、プレイミスが起きてしまう。 • 低いフレームレートでゲーム体験が劣化してしまう
最適化の前に覚えておきたい法則 • 「パレートの法則」 • 通称:80:20の法則。全体の数字の大部分は、全体を構成するごく一部 によるものである • 処理負荷となっている部分は、プロジェクトのごく一部分によって起 きている
最適化の前に覚えておきたい法則 処理の一部分を直せば、 大体の問題は解決する
最適化の前に覚えておきたい法則 直すべき処理を見極めるのが 最優先事項!!
最適化の前に覚えておきたい法則 いきなり修正作業を始めては ダメ 体重も測らず、ダイエットを始めてしまうのが ダメなのと一緒
いきなり最適化作業をしてはダメな理由 • 何を直すべきかもわからないまま当てずっぽうに作業をしても、時間を 浪費してしまう • どの程度の負荷があったのか把握しておかないと、作業によってどの程 度効果があったのか測れず、修正がうまくいったのかわからなくなる
プロファイリング超重要 最適化の前に プロファイリングをしてく ださい!絶対に!絶対にしてください! これは超重要案件です!!! 最適化への道はプロファイリングすることから始まる
最適化のための手順 1.ゲーム内の処理負荷となっている箇所を特定するためプロ ファイリングする 2.負荷となっている処理の内容が特定出来たら、直すための算 段を立てる 3.実際に作業して直す
最適化のための手順 1.ゲーム内の処理負荷となっている箇所を特定するためプロ ファイリングする 2.負荷となっている処理の内容が特定出来たら、直すための算 段を立てる 3.実際に作業して直す この講演は、ココの話がメイン
プロファイリングについて • 処理毎に掛った時間、メモリの使用状況を確認する作業 • Unity標準機能で Profiler が用意されているので、こちらを使って 計測可能 • より詳細な事は各プラットフォームが提供しているネイティブの Profilerがあるが、大まかな問題把握では UnityのProfilerで十分
プロファイリングについて まずは、UnityのProfilerを 使おう!!
Unity Profilerについて • Editor上でプレイした時に、CPU / GPU / Rendering / Memory / Audio / Physics / uNet / Video Player / UI / GIなどの状況を確認できる • Editor上でのプレイだけでなく、Android/iPhone上での実行のパフォーマ ンスも見られる ※Video Playerは Unity 5.6から利用可能 UIは Unity 2017.1から利用可能 GI(Global Illumination)は Unity 2017.2から利用可能
Profiler使い方 デモ
Unity Profilerの使い方 Menuから Window -> Profiler を選択すると、このウィン ドウが出てくる
Editor実行中に処理負荷を見られる Editor上で Playボタンを押せば、 負荷がグラフで見られる
色々な種類の情報を確認できる CPU/Rendering/ Memory に関する情報が カテゴリ別にグラフ表示
もし見たい項目がなかった時は… 項目が表示されていない場合は、 ココで追加
選択した項目の詳細情報の確認 現在選択中の項目の 詳細情報がコチラに 表示される
Unity Profilerを実機と繋げる 「Active Profiler」をクリックす ることで、プロファイルする 対象が切り替えられる AndroidやiOSの実機上での実行 もプロファイル出来る ※1.Developビルドしたアプリのみ接続可能 ※2.同じネットワーク環境かに接続、もしくは 有線でPCとつなぐ必要がある
実機とPCを同じWifiに繋いで アプリを起動するだけ
ただ大体の問題はEditor上で 見つけられる。 Editor上での実行の方が早く て楽なので、オススメ
Profiler の使い方について 学んだので早速実践編 ~ケーススタディ~
ケーススタディ • 最適化を行いたいシチュエーションによって、見るべき場所も変わって くる • メモリ使用量が多くて、ゲームが不正終了してしまう • ロード時間が長い • ゲームプレイ中にカクツキが頻発してしまいストレスフル • 低いフレームレートでゲーム体験が劣化してしまう
~ケーススタディ~ メモリ使用量が多い場合
メモリ使用量が多い時に考える事 • 単純にメモリ使用量が多いのか?それともリークしているのか? • C#メモリが多いのか? Unityメモリが多いのか? ※リークとは未使用のものがメモリに残り続けてしまい、 必要以上にメモリを消費してしまう現象
メモリがリークしているかチェックする メモリの詳細項目に読み込んでいる Texture・Mesh等の数がある。 繰り返しプレイしていて、右肩上が りに数字が増えていたらリークして いる可能性大
メモリリークしているか 雰囲気でわかる方法 メモリを沢山積んでいる端末でも、 沢山遊んでメモリがたりず落ちるな らメモリリークの可能性大!!
C#メモリが大きいのか、 Unityメモリが大きいのか • Unityが使用するメモリは大きく分けて二つある • C#メモリ(Mono Memory) • Unityメモリ →どちらが大きいかによって取るアクションは大きく変わってくる
C#メモリが大きいのか、 Unityメモリが大きいのか Memoryの詳細に、C#メモリ・Unityメモリの使用状況がある
C#メモリとUnityメモリについて • C# メモリ • C# スクリプト側で使用しているメモリで、Garbage Collectionされる • 一度メモリをReserve(予約)してから使う。C#用に予約済みとなったメ モリはアプリ終了まで二度と返されない • Unityメモリ • Texture, Mesh, Animation などのアセットのデータで主に占められるメ モリ
メモリのイメージ図 C#使用メモリ 未使用 C#用に予約したメモリ Unityメモリ アプリで使用している全体メモリ
C#のメモリでの着目点 • Used(現在使用中)よりも、Reserved(予約)の方に着目 • Editor上での実行の場合はEditorが使ったメモリも換算されてしまうの で、実機でのチェックが望ましい • Reserved(予約) が大きすぎる場合、どこかで一時的にC#メモリが膨らん でいる可能性がある • ファイル読み込みや、通信のために一時的に大量のC#メモリを使用し ていないか?
Unityメモリでの着目点 • メモリ上にある各Asset毎のメモリ内の容量をチェック • Memory Profilerを、Detailed (詳細) ビューに切り替えて確認 • 別途 Unity Technologies製のEditor拡張ツールもあり • 出来ることは殆ど同じだが、ちょっとグラフィカルで見やすい
Memory Profiler使い方 デモ
Memory Profiler の使い方 ここを押して、Simpleビューと Detailビューの切り替えをする
Memory Profiler の使い方 Take Sampleボタンを押すと、メモ リの詳細を調べられる
Memory Profiler の使い方 どのアセットがメモリに読み込まれ ていて、どれだけメモリを使用して いるかが一覧でわかる
UnityのMemory Profiler https://bitbucket.org/Unity-Technologies/memoryprofiler にて配布 これをプロジェクトに組み込む必要がある
メモリが多かった時の対策 • C#メモリ • C#スクリプトの見直しを行う • 特にファイル読み込みや通信時等にメモリを多く消費していないか? • Unityメモリ • 余計なアセットが読み込まれないようにする • 必要であれば、読み込みのタイミングをずらす等も視野に • 必要以上に大きいアセットは圧縮等を行うようにする
メモリが足りなくて落ちるときの図 YES メモリリーク? メモリリークの原因を 探して対処 NO 大きいのは C#メモリ? Unityメモリ? Unityメモリ どのアセットが多く使っている か特定して対処する C#メモリ C#のソースを見直す。(特にファ イル読み込みや通信周り)
~ケーススタディ~ ロードが長い場合
ロード時間が長い時に考える事 • 本当にロード時間が長いのか?それとも初期化処理が重いのか? • 読み込むデータは適切か?余計なデータを読んでいないか?
ロードが重かった時のデモ
ロードが重かった時のデモ グラフが一気に跳ね上がったところが、 ロードをしたタイミングなので、ここ をクリックして、その時の詳細を追っ ていくことで負荷を見ていく
ロードが重かった時のデモ [スクリプト名].Awakeという形で C#スクリプトと対応している。
ロードが重かった時のデモ Awakeの中のLogStringToConsole が ロード時間の4分の1近く…
プロファイリングする時の注意 負荷になっていたのが Debug.Log書き出しだった…
プロファイリングする時の注意 プロファイリングをするとき は Debug.LogをOFFに! Debug.logger.logEnabled = false; でログ書き出し処理を無効に出来る。 ※理想は全部のDebug.Log呼び出しを#ifdefなどで 事前に括って置いて呼び出しそのものをしない事
改めて… ロードが重かった時のデモ
ロードが重かった時のデモ(改) Texture.AwakeFromLoadで0.35秒。Texture 読み込みに多くの時間がかかってい るのがわかる
ロードが重かった時のデモ(改) CPUの詳細情報をTimelineへ変更する事で、 メインスレッド以外の様子がわかるよ うになる
ロードが重かった時のデモ(改) 別スレッドで行っているファイル 読み込み処理も確認できる
ロードが重かった時のデモ(改) • Memory ProfilerのDetailedビューを使って余計なデータを読み込んでいな いか、読み込んだデータのサイズをチェック 読み込まれるはずのない データも読み込まれてし まっていないか? データサイズが大きすぎ ないか?
AssetBundleを使っている時の注意 AssetBundleを使っている場合、予期せず重複 したデータを含んでしまっている事がよく あるので注意
ロードが長い時の処理 DebugログをOFFに 長いのは 初期化処理? ロード処理? 初期化処理 ロード処理 ロード済みデータを確認 余計なデータがあれば読み込まないように 大きすぎるデータは圧縮等検討 C#スクリプトを見直す
~ケーススタディ~ 一瞬、画面が固まった場合
一瞬だけ画面が固まる場合 • 裏でロード処理を行っている等の心当たりがない場合は、ほとんどの場 合 GC(Garbage Collection)が走っている • GCとは、C#メモリが足りなくなった時に整理して未使用のメモリを再 び使えるようにする処理 • GCは膨大な処理時間を取られる • まずはGCが起きていないかProfilerでチェック
GCが起きていないか 確認デモ
GCが起きていないか確認デモ 項目をクリックするとグラフに表示をする/しな いが選択できる GarbageCollectorのみをONにする事で発見しやすく なる
GCが頻繁に起きていた時の対策 • まずは、どのC#スクリプトで多く消費しているか特定する • C#のメモリ使用を可能な限り抑えるように書き換える • 文字列操作はメモリを都度使用するので、扱いには注意! • StringBuilderクラスを使うようにしましょう • 特に毎フレームUpdate処理でのメモリ確保は控える
GCの発生箇所特定デモ