ユニティ・テクノロジーズ・ジャパン
名雪 通
Burstを使って
SHA-256のハッシュ計算を
高速に行う話
本日のソースコード:
https://github.com/tnayuki/Unity-BurstSHA256
Burst
ご存知ですよね?
https://learning.unity3d.jp/4968/
Burstは速い
しかし
‒Toru Nayuki
大いなるスピードには大いなる責任が伴う
いろいろ使えないものも多いし、
基本的にはメモリ→メモリ的な処理になる
ファイル入力ぐらいしたい
お題
ファイル(1GBのランダムデータ)を読み込んで
SHA-256のハッシュ値を計算する
Burst化したジョブからは
ファイル読み込みできない
(Fileクラスが使えないので)
↓
ファイルを読み込んでから
Burstコンパイルされたコードを呼ぶ
こんな感じでSHA-256のハッシュを計算するルーチンを構造体として実装して、
構造体とstaticメソッドにBurstCompile属性をつける
こんな感じで64KBずつファイルから読み込んで
BurstでコンパイルされたSHA-256のルーチンを呼ぶ
Burstコンパイル無効
Burstコンパイル有効
ところで
お気づきだろうか?
Burstでコンパイルされたメソッドを普通に呼んでいる
以前はdelegateを使う必要があった
Burst 1.5.0から使えるようになったDirect Call
※ILのポストプロセスによって実現されている
https://learning.unity3d.jp/5005/
実はジョブ向け?の
ファイル読み込みのための仕組みがある
AsyncReadManager
ファイルの読み込む部分とバッファを
構造体の配列にして渡す
読み込むファイル名
ファイル名がstring型なのでBurstのジョブから呼べない
ファイルの読み込む部分とバッファを
構造体の配列にして渡す
全部まとめてしか完了状態がわからない
ジョブの中でファイルを
ストリーミング的に読み込むには向いていない?
ジョブの中でファイルが読み込めない
なら
OSに読ませればいいじゃない
メモリマップトファイルを使ってみよう
※ここからの話はすべてのプラットフォームで対応可能な方法ではありません
メモリマップトファイルを使ってみよう
メモリマップトファイルとは
近代OSの仮想メモリ機構の一部として実装されている、
ファイルをプロセスのアドレス空間に直接マッピングする仕組み。
スワップファイルの機構も同じ仕組みで実装されている(ことが多い)。
メモリマップトファイルとは
近代OSの仮想メモリ機構の一部として実装されている、
ファイルをプロセスのアドレス空間に直接マッピングする仕組み。
スワップファイルの機構も同じ仕組みで実装されている(ことが多い)。
通常のメモリアクセスとしてファイルにアクセスできる
ファイルをメモリマッピングしたアドレスを
NativeArrayとして返すNativeContainerを作った
こんな感じでジョブ化したSHA-256を呼ぶ
(ジョブの中では普通のNativeArrayとしてアクセスできる!)
※ここまでの話はすべてのプラットフォームで対応可能な方法ではありません
ジョブは入力がファイルであることを意識せずに実装できるし、
並列処理もしやすいので
意外と便利かも…
例: 独自形式のファイルからメッシュを生成するなど
おまけ
SHA-256と言えば…
とある
クラウドソーシングサイト
にて
ここに注目
入力は任意のものではなく、限定されている
32バイト 8bit = 2^256通り
Burstを使えば1GBを10秒ほど
でハッシュ計算できるので…
2256
× 32
230
× 10
= (秒)
3.4508732 × 1070
2256
× 32
230
× 10
= (秒)
3.4508732 × 1070
= (年)
1.0942647 × 1063
2256
× 32
230
× 10
1,094那由多年かかる
無理
以上
ご清聴
ありがとうございました

Burstを使ってSHA-256のハッシュ計算を高速に行う話