Upgrade to Pro — share decks privately, control downloads, hide ads and more …

たのしいUnsafeUtility

08a7d188d046f35b2501e686616f71bd?s=47 mao
September 23, 2019

 たのしいUnsafeUtility

[非公式] Unite Tokyo 2019 Eve2 LT Fes LT登壇資料です
https://connpass.com/event/139403/

※記載しているリンクには直接アクセスできないので、スライド中で記載しているリンクの一部を以下に記載
-----------------------------------------------------------------
▽ 参考/関連リンク

・【Unity】UnsafeUtilityについて纏めてみる
https://qiita.com/mao_/items/fc9b4340b05e7e83c3ff

・【Unity】UnsafeUtility基礎論【入門者向け】
https://qiita.com/pCYSl5EDgo/items/4b5a5e089eabc8f4387d

・Memory Management of C# with Unity Native Collections
https://www.slideshare.net/neuecc/memory-management-of-c-with-unity-native-collections

・unsafe - C# によるプログラミング入門 | ++C++; // 未確認飛行 C
https://ufcpp.net/study/csharp/sp_unsafe.html

・Span Struct
https://docs.microsoft.com/ja-jp/dotnet/api/system.span-1?view=netstandard-2.1

・Span構造体 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C
https://ufcpp.net/study/csharp/resource/span/

・Spanを使うべき5つの理由
https://qiita.com/GlassGrass/items/cea3c6f91413c3582b5f

・xoofx/UnityNuGet
https://github.com/xoofx/UnityNuGet

・Unity で Span とかを使う
https://github.com/ufcpp/UnitySamples/tree/master/SpanUnsafeBuffers

・※ ポインタをNativeArrayに変換する例
https://gist.github.com/mao-test-h/51b4e3f143b10d0dd12a8b1c81721133

・※ NativeArrayの内部実装 (UnityCsReferenceより)
https://github.com/Unity-Technologies/UnityCsReference/blob/master/Runtime/Export/NativeArray/NativeArray.cs

-----------------------------------------------------------------
▽ その他参考リンク

・もなふわすい~とる~む
https://www.showroom-live.com/monaka-007

・もなふわすい~とる~む - プロフィール
https://www.showroom-live.com/room/profile?room_id=223749

・巻乃もなか(時間遡行中) - Twitter
https://twitter.com/monaka_0_0_7

08a7d188d046f35b2501e686616f71bd?s=128

mao

September 23, 2019
Tweet

Transcript

  1. Unite Tokyo 2019 Eve2 LT Fes (2019/9/23)

  2. 自己紹介 mao Twitter: @TEST_H_ • ゴリラ 推しのVは 巻乃もなか もなふわすい~とる~むはいいぞ

  3. 今回話す内容について Unity2018からDOTSが入り始め、 エンジン側のネイティブメモリ領域を使う機会が出てきた ◦ 代表的なのはNativeContainerの実装とか ◦ これらはマネージヒープ(参照型)を利用しない ▪ → アンマネージドメモリを利用

    ※DOTSとは「 Data-Oriented Technology Stack」の略。NativeContainer、JobSystem、ECS、Burstと言ったデータ指向型の総称と言う認識
  4. 今回話す内容について 今回はNativeContainerの内部実装でも使用されている UnsafeUtility/unsafe C#に関する幾つかのTipsをシェア • 主にメモリ管理周りを中心に • ここらの特性などを理解しておくとDOTSに関する実装で 色々と応用を利かせられるかもしれない Unityバージョンは

    2018.4.8f1で検証 ※バージョンアップで挙動が変わる可能性もあるので注意...
  5. 今回話す内容について 覚えて何に使える? ◦ DOTSに関する処理を書く際のポインタの扱い ▪ NativeContainerを自作する際 ▪ ポインタによる間接参照の取り扱い ◦ それ以外で言えばエクストリームなC#の実装とか

    ▪ 頑張ればC#でC言語を書ける(?) ※ 内容的にメモリ管理に慣れ親しんだ方には退屈になる所もあるかも ...
  6. 目次 • このスライドの注意点 • UnsafeUtilityとは? • Tips 集 ◦ 治安を維持する為に

    ◦ Allocatorの違いについて ◦ その他覚えておくと便利な技術
  7. このスライドの注意点

  8. このスライドの注意点 前提としてunsafeを推奨する話ではない ◦ 使い方を誤ると世紀末になる可能性あり ▪ → クラッシュ、厄介な不具合、etc...

  9. このスライドの注意点 前提としてunsafeを推奨する話ではない ◦ 学んだからと言って無理して使う必要は無いと思われ ◦ ご利用は計画的に ▪ → 影響範囲はなるべく狭くするなど •

    ※今日は主にこの話
  10. このスライドの注意点 • 内容的にポインタ周りの知識は必要になるかも ◦ スライド中では概念レベルからの解説はしない • まだ公式の情報が少ない...? ◦ 間違い/抜け/非推奨とかあるかも... •

    実は他に良いやり方があるかも... ◦ → シェアしてもらえると嬉しい!!
  11. UnsafeUtilityとは?

  12. UnsafeUtilityとは? Unity2018系統から追加されたAPI. `Unity.Collections.LowLevel.Unsafe`以下に封印されている. → メモリに関する操作を行うためのユーティリティクラス

  13. UnsafeUtilityとは? 出来ること • メモリに関する操作 ◦ Blittable型チェック(IsBlittable) ◦ コピー(MemCpy)、クリア(MemClear) • エンジン側が確保するネイティブメモリ領域の操作が可能

    ◦ 割り当て(Malloc) ◦ 解放(Free)
  14. UnsafeUtilityとは? 使用例やパフォーマンス等については以下を参照 • 【Unity】UnsafeUtilityについて纏めてみる ◦ https://qiita.com/mao_/items/fc9b4340b05e7e83c3ff ◦ • 【Unity】UnsafeUtility基礎論【入門者向け】 ◦

    https://qiita.com/pCYSl5EDgo/items/4b5a5e089eabc8f4387d
  15. Tips集

  16. 1. 治安を維持する為に

  17. 治安を維持する為に • Mallocしたら寿命は自分で管理する必要がある • 破棄を忘れたらエラーも出ずにメモリリークし続ける ◦ ※後述するがAllocatorによって挙動が変わる ◦ • ポインタをそのまま使うのは怖い...

    • ミスるとクラッシュ/厄介な不具合
  18. Allocatorの違いについて 補足: 何が怖いか? • 例えば普段C#を使う上で 例外が投げられるような処理を書いても投げられない ◦ e.g. 範囲外アクセス、etc… →

    厄介な形で影響が出るかもしれない
  19. 治安を維持するためには?

  20. 治安を維持する為に NativeArray<T>を参考にしてみる → 治安維持するための仕組みが実装されている • コンストラクタで割り当て時にセーフティ機能を設定 ◦ DisposeSentinelでAllocatorに応じたリークの追跡 • インデクサやDisposeでバリデーション

    ◦ 範囲外アクセスや多重解放時には例外を投げる ◦ → ポインタ直にを触らせない
  21. 治安を維持する為に NativeArrayを使う/若しくは同等の機能の実装を心がける → デリケートな部分は表に出さない • 可能な限り直接のMalloc/Freeは控える ◦ NativeArray<T>で確保/破棄 ◦ 自身で実装するならセーフティ機能を取り入れる

    • ポインタを直接触らせない工夫 ◦ 範囲チェック、生存チェック、etc...
  22. 治安を維持する為に 難しい場合もある... → NativeArray<T>を持つ構造体を   ポインタやNativeArray<T>で持ちたい

  23. 治安を維持する為に 難しい場合もある... → NativeArray<T>を持つ構造体を   ポインタやNativeArray<T>で持ちたい ★下記のモヒカンの構造体をポインタやNativeArrayで持ちたい

  24. 治安を維持する為に 難しい場合もある... → NativeArray<T>を持つ構造体を   ポインタやNativeArray<T>で持ちたい • 今のモヒカンは非Blittableなので持てない ◦ セーフティ機能の大体は参照型

    ◦ → 故にモヒカンは参照型を含むために非Blittable ※Blittable型とは?簡単に言えばマネージド (C#)とネイティブ(C++)でメモリレイアウトが同じになる型のこと
  25. NativeArray<T>では無くポインタをフィールドに持たせる → モヒカンをBlittableに 治安を維持する為に ※GetUnsafePtr()と言った拡張メソッドからptrを取得可能

  26. 治安を維持する為に このままだとポインタが裸族 → 直接使うのは怖いので状況に応じてプロパティなどで変換 ◦ NativeArray<T>とかで包み込む(例はNativeArray)

  27. 治安を維持する為に ※ポインタをNativeArrayに変換する方法について 萌えポイントとしてはセーフティ機能を考慮しないと インデクサアクセス時にNullエラーで死ぬ https://gist.github.com/mao-test-h/51b4e3f143b10d0dd12a8b1c81721133

  28. 治安を維持する為に 補足: NativeArrayからセーフティ機能を抜いたらunmanaged? C#7の段階ではgenericsはunmanagedと判定されない → ポインタとして定義することが出来ない • C# 8から可能 ◦

    ※Plugin化すれば一応C#8は使える • ポインタは無理だが NativeArrayの生成は可能 → Blittableではある
  29. 治安を維持する為に この章のまとめ • セーフティ機能は可能な限り取り入れる • テスト書こう。Testable推奨 • NativeArray以外のNativeContainerも活用/参考に ◦ NativeSlice

    ◦ Unity.Collections パッケージ (preview)
  30. 2. Allocatorの違いについて

  31. Allocatorの違いについて メモリを確保する際のAllocatorは以下の物から指定可能 → メモリの生存時間と割り当て/解放時間のトレードオフ Allocator 割り当て/解放 速度 寿命 Temp ◦

    1フレーム TempJob △ 4フレーム Persistent ☓ 無限 Invalid / None - -
  32. Allocatorの違いについて 萌えポイントとしてはAllocatorによってリーク時や メモリ不正アクセス時の挙動が変わる様に見受けられた? ※Standaloneビルド/Editor上で確認 Allocator メモリリーク時 メモリ不正アクセス時 Temp 何もなし 何もなし

    TempJob エラー出力 (処理によっては)エラー出力 Persistent 何もなし (処理によっては)クラッシュ ※あくまで自分が確認した範囲の例。例外はあると思うのでご参考までに ...
  33. Allocatorの違いについて 萌えポイントとしてはAllocatorによってリーク時や メモリ不正アクセス時の挙動が変わる様に見受けられた? ※Standaloneビルド/Editor上で確認 Allocator メモリリーク時 メモリ不正アクセス時 Temp 何もなし 何もなし

    TempJob エラー出力 (処理によっては)エラー出力 Persistent 何もなし (処理によっては)クラッシュ ※あくまで自分が確認した範囲の例。例外はあると思うのでご参考までに ...
  34. Allocatorの違いについて Allocatorの挙動を踏まえて積極的にテスト • Tempだとエラーに気づきにくい? ◦ 裏技臭いがTempで行けるところは 敢えて別のAllocatorでテストするのもありかも • そもそもとして前述の保守的な実装を心がけるべき ◦

    もし直にMallocする箇所などが出てきたら参考程度に...
  35. 3. その他覚えておくと便利な技術

  36. その他覚えておくと便利な技術 C#のunsafeコード • 固定長バッファ • stackalloc • マネージド配列からのポインタ取得 ◦ ※NativeArrayはこの手法でポインタを取得してMemCpyしてる

  37. その他覚えておくと便利な技術 使い所が適していればstackallocが便利 • メモリが必要な際にMallocしなくても良い • 高速 • デカすぎるとstack overflowするので注意

  38. その他覚えておくと便利な技術 C#のunsafeコード 参考 • unsafe - C# によるプログラミング入門 | ++C++;

    // 未確認飛行 C ◦ https://ufcpp.net/study/csharp/sp_unsafe.html
  39. その他覚えておくと便利な技術 System.Memory<T> • Span<T> • Unityで使うには? ◦ ① .NET Standard

    2.1対応を待つ ◦ ② NuGetから取得 ▪ xoofx/UnityNuGet ※GitHubで検索 ▪ 手動で入れる ※ソースは参考/関連リンク 参照
  40. その他覚えておくと便利な技術 System.Memory<T> 参考 • Span<T> Struct ◦ https://docs.microsoft.com/ja-jp/dotnet/api/system.span-1?view=netstandard-2.1 • Span構造体

    - C# によるプログラミング入門 | ++C++; // 未確認飛行 C ◦ https://ufcpp.net/study/csharp/resource/span/ • Span<T>を使うべき5つの理由 ◦ https://qiita.com/GlassGrass/items/cea3c6f91413c3582b5f
  41. 参考/関連リンク

  42. 参考/関連リンク • 【Unity】UnsafeUtilityについて纏めてみる ◦ https://qiita.com/mao_/items/fc9b4340b05e7e83c3ff • 【Unity】UnsafeUtility基礎論【入門者向け】 ◦ https://qiita.com/pCYSl5EDgo/items/4b5a5e089eabc8f4387d •

    Memory Management of C# with Unity Native Collections ◦ https://www.slideshare.net/neuecc/memory-management-of-c-wi th-unity-native-collections
  43. 参考/関連リンク • unsafe - C# によるプログラミング入門 | ++C++; // 未確認飛行

    C ◦ https://ufcpp.net/study/csharp/sp_unsafe.html • Span<T> Struct ◦ https://docs.microsoft.com/ja-jp/dotnet/api/system.span-1?view=netstandard-2.1 • Span構造体 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C ◦ https://ufcpp.net/study/csharp/resource/span/ • Span<T>を使うべき5つの理由 ◦ https://qiita.com/GlassGrass/items/cea3c6f91413c3582b5f
  44. 参考/関連リンク • xoofx/UnityNuGet ◦ https://github.com/xoofx/UnityNuGet • Unity で Span とかを使う

    ◦ https://github.com/ufcpp/UnitySamples/tree/master/SpanUnsafeBuffers ◦ • ※ ポインタをNativeArrayに変換する例 ◦ https://gist.github.com/mao-test-h/51b4e3f143b10d0dd12a8b1c81721133 • ※ NativeArrayの内部実装 (UnityCsReferenceより) ◦ https://github.com/Unity-Technologies/UnityCsReference/blob/master/Runtime/Export/Nativ eArray/NativeArray.cs
  45. その他 参考リンク

  46. 参考リンク • もなふわすい~とる~む ◦ https://www.showroom-live.com/monaka-007 • もなふわすい~とる~む - プロフィール ◦

    https://www.showroom-live.com/room/profile?room_id=223749 • 巻乃もなか(時間遡行中) - Twitter ◦ https://twitter.com/monaka_0_0_7
  47. 参考リンク • もなふわちゃんねる ◦ https://www.youtube.com/channel/UCZY07-x22jI7rNGJLZn7XPg • 5分でわかる巻乃もなか ◦ https://www.youtube.com/watch?v=Q7D82s1u6-E •

    自己紹介 ◦ https://www.youtube.com/watch?v=TMypE0pNWI8
  48. Thank you!