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

たのしいUnsafeUtility

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

mao

September 23, 2019
Tweet

More Decks by mao

Other Decks in Technology

Transcript

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

    View full-size slide

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

    View full-size slide

  3. 今回話す内容について
    Unity2018からDOTSが入り始め、
    エンジン側のネイティブメモリ領域を使う機会が出てきた
    ○ 代表的なのはNativeContainerの実装とか
    ○ これらはマネージヒープ(参照型)を利用しない
    ■ → アンマネージドメモリを利用
    ※DOTSとは「 Data-Oriented Technology Stack」の略。NativeContainer、JobSystem、ECS、Burstと言ったデータ指向型の総称と言う認識

    View full-size slide

  4. 今回話す内容について
    今回はNativeContainerの内部実装でも使用されている
    UnsafeUtility/unsafe C#に関する幾つかのTipsをシェア
    ● 主にメモリ管理周りを中心に
    ● ここらの特性などを理解しておくとDOTSに関する実装で
    色々と応用を利かせられるかもしれない
    Unityバージョンは 2018.4.8f1で検証
    ※バージョンアップで挙動が変わる可能性もあるので注意...

    View full-size slide

  5. 今回話す内容について
    覚えて何に使える?
    ○ DOTSに関する処理を書く際のポインタの扱い
    ■ NativeContainerを自作する際
    ■ ポインタによる間接参照の取り扱い
    ○ それ以外で言えばエクストリームなC#の実装とか
    ■ 頑張ればC#でC言語を書ける(?)
    ※ 内容的にメモリ管理に慣れ親しんだ方には退屈になる所もあるかも
    ...

    View full-size slide

  6. 目次
    ● このスライドの注意点
    ● UnsafeUtilityとは?
    ● Tips 集
    ○ 治安を維持する為に
    ○ Allocatorの違いについて
    ○ その他覚えておくと便利な技術

    View full-size slide

  7. このスライドの注意点

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  10. このスライドの注意点
    ● 内容的にポインタ周りの知識は必要になるかも
    ○ スライド中では概念レベルからの解説はしない
    ● まだ公式の情報が少ない...?
    ○ 間違い/抜け/非推奨とかあるかも...
    ● 実は他に良いやり方があるかも...
    ○ → シェアしてもらえると嬉しい!!

    View full-size slide

  11. UnsafeUtilityとは?

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  14. UnsafeUtilityとは?
    使用例やパフォーマンス等については以下を参照
    ● 【Unity】UnsafeUtilityについて纏めてみる
    ○ https://qiita.com/mao_/items/fc9b4340b05e7e83c3ff

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

    View full-size slide

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

    View full-size slide

  16. 治安を維持する為に
    ● Mallocしたら寿命は自分で管理する必要がある
    ● 破棄を忘れたらエラーも出ずにメモリリークし続ける
    ○ ※後述するがAllocatorによって挙動が変わる

    ● ポインタをそのまま使うのは怖い...
    ● ミスるとクラッシュ/厄介な不具合

    View full-size slide

  17. Allocatorの違いについて
    補足: 何が怖いか?
    ● 例えば普段C#を使う上で
    例外が投げられるような処理を書いても投げられない
    ○ e.g. 範囲外アクセス、etc…
    → 厄介な形で影響が出るかもしれない

    View full-size slide

  18. 治安を維持するためには?

    View full-size slide

  19. 治安を維持する為に
    NativeArrayを参考にしてみる
    → 治安維持するための仕組みが実装されている
    ● コンストラクタで割り当て時にセーフティ機能を設定
    ○ DisposeSentinelでAllocatorに応じたリークの追跡
    ● インデクサやDisposeでバリデーション
    ○ 範囲外アクセスや多重解放時には例外を投げる
    ○ → ポインタ直にを触らせない

    View full-size slide

  20. 治安を維持する為に
    NativeArrayを使う/若しくは同等の機能の実装を心がける
    → デリケートな部分は表に出さない
    ● 可能な限り直接のMalloc/Freeは控える
    ○ NativeArrayで確保/破棄
    ○ 自身で実装するならセーフティ機能を取り入れる
    ● ポインタを直接触らせない工夫
    ○ 範囲チェック、生存チェック、etc...

    View full-size slide

  21. 治安を維持する為に
    難しい場合もある...
    → NativeArrayを持つ構造体を
      ポインタやNativeArrayで持ちたい

    View full-size slide

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

    View full-size slide

  23. 治安を維持する為に
    難しい場合もある...
    → NativeArrayを持つ構造体を
      ポインタやNativeArrayで持ちたい
    ● 今のモヒカンは非Blittableなので持てない
    ○ セーフティ機能の大体は参照型
    ○ → 故にモヒカンは参照型を含むために非Blittable
    ※Blittable型とは?簡単に言えばマネージド (C#)とネイティブ(C++)でメモリレイアウトが同じになる型のこと

    View full-size slide

  24. NativeArrayでは無くポインタをフィールドに持たせる
    → モヒカンをBlittableに
    治安を維持する為に
    ※GetUnsafePtr()と言った拡張メソッドからptrを取得可能

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  27. 治安を維持する為に
    補足: NativeArrayからセーフティ機能を抜いたらunmanaged?
    C#7の段階ではgenericsはunmanagedと判定されない
    → ポインタとして定義することが出来ない
    ● C# 8から可能
    ○ ※Plugin化すれば一応C#8は使える
    ● ポインタは無理だが
    NativeArrayの生成は可能
    → Blittableではある

    View full-size slide

  28. 治安を維持する為に
    この章のまとめ
    ● セーフティ機能は可能な限り取り入れる
    ● テスト書こう。Testable推奨
    ● NativeArray以外のNativeContainerも活用/参考に
    ○ NativeSlice
    ○ Unity.Collections パッケージ (preview)

    View full-size slide

  29. 2. Allocatorの違いについて

    View full-size slide

  30. Allocatorの違いについて
    メモリを確保する際のAllocatorは以下の物から指定可能
    → メモリの生存時間と割り当て/解放時間のトレードオフ
    Allocator 割り当て/解放 速度 寿命
    Temp ○ 1フレーム
    TempJob △ 4フレーム
    Persistent ☓ 無限
    Invalid / None - -

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  33. Allocatorの違いについて
    Allocatorの挙動を踏まえて積極的にテスト
    ● Tempだとエラーに気づきにくい?
    ○ 裏技臭いがTempで行けるところは
    敢えて別のAllocatorでテストするのもありかも
    ● そもそもとして前述の保守的な実装を心がけるべき
    ○ もし直にMallocする箇所などが出てきたら参考程度に...

    View full-size slide

  34. 3. その他覚えておくと便利な技術

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  37. その他覚えておくと便利な技術
    C#のunsafeコード
    参考
    ● unsafe - C# によるプログラミング入門 | ++C++; // 未確認飛行 C
    ○ https://ufcpp.net/study/csharp/sp_unsafe.html

    View full-size slide

  38. その他覚えておくと便利な技術
    System.Memory
    ● Span
    ● Unityで使うには?
    ○ ① .NET Standard 2.1対応を待つ
    ○ ② NuGetから取得
    ■ xoofx/UnityNuGet ※GitHubで検索
    ■ 手動で入れる ※ソースは参考/関連リンク 参照

    View full-size slide

  39. その他覚えておくと便利な技術
    System.Memory
    参考
    ● 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

    View full-size slide

  40. 参考/関連リンク

    View full-size slide

  41. 参考/関連リンク
    ● 【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

    View full-size slide

  42. 参考/関連リンク
    ● 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

    View full-size slide

  43. 参考/関連リンク
    ● 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

    View full-size slide

  44. その他 参考リンク

    View full-size slide

  45. 参考リンク
    ● もなふわすい~とる~む
    ○ 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

    View full-size slide

  46. 参考リンク
    ● もなふわちゃんねる
    ○ https://www.youtube.com/channel/UCZY07-x22jI7rNGJLZn7XPg
    ● 5分でわかる巻乃もなか
    ○ https://www.youtube.com/watch?v=Q7D82s1u6-E
    ● 自己紹介
    ○ https://www.youtube.com/watch?v=TMypE0pNWI8

    View full-size slide