どうも千利休です。
久々にローレベルなところからプログラミングしたいなあということで今回はMetalに関してさらっとどんなことができるのかを調べてきました。
カンファレンスなどで聞いてきて事前知識があるので戸惑うことはなかったですが、なにぶん日本語のドキュメントは少ないので、慣れない英語を読みながらになります。
間違っている箇所等ありましたらお教えください。
Melalのコンセプト
metal for DevelopersというリファレンスやサンプルをAppleさんが作ってくれています。基本的にはいいことしか書いていないのでやや過剰なところもあるかと思いますが読んでいきましょう。
ちなみにリンクはこちら
Metal for Developers - Apple Developer
- 低いCPUオーバーヘッド
- 最適なGPUパフォーマンス
- 連続的なプロセッサの並列処理
- 効率的な資源管理
が基本コンセプトらしい、これだけ言われて理解できる人なんかいないでしょう。
ざっくりいうと今までより処理が早く描画できるようになったよ!ということです。
ではなぜそうなったのか、を解説して聞きましょう。
AppleのCPUに最適化されたAPI
MetalはAplle A7チップ以降に採用された今までよりローレベルなグラフィックAPIです。
今まではOpenGLESというAndroidなどでも使われている汎用的なグラフィックAPIが使われていました。
汎用的なAPIはソフトウェア開発者が各ハードのことを考えなくてもいいという部分はあるのですが、そのぶんハードウェアに最適化できないため余計なオーバーヘッドを持ってしまいます。
それこそ、シェーダコンパイルがドライバレベルで走るとかが代表例です。
UnityやUnrealEngineといったものを使えばあまり気にしなくて済みますが、実はこのギラフィックスAPIはかなりの技術革新であり、より専門的な知識が必要になります。
マルチスレッド処理
基本的にDrawメソッドを通じてコマンドキューを発行しており、今までだとそれがシングルスレッドのみでしか行えませんでした。
今回はそれがマルチスレッドで行えるようになり、分散させることが可能です。
これは時代の流れでもあるマルチスレッドプログラミングと一緒で、スレッド数を意識した開発が行えるようになります。
メモリ共有
これもなかなかにでかいです。
従来はCPUのメモリの情報をGPUに転送するという処理が必要でした。
CPUとGPUのメモリは非同期なため、何かデータを書き換えたい場合はCPUで情報を作り直してGPUに送るか、シェーダで加工する必要がありました。
これがかなりのオーバーヘッドの原因の一つでもあり、それを解決するのにVBOなど転送データを使い回す必要などもありました。
しかしMetalの場合、それがありません。
CPUとGPUのメモリが共有されます。
そのため、CPU側で書き換えたメモリがそのままGPUで使用されるためオーバーヘッドがかなり抑えられているということになります。
例えば今までGPU側で行なっていた処理をCPU側で行なうこともその逆も可能になり、より高速にチューニングできます。
試していないのでまだわかりませんが、GPUの処理中に意図的にCPU側でメモリを書き換えたらレンダリングを壊すことにもなると思うのでメモリアクセスをより気にする必要があると思います。まあその辺の仕組みはあると思いますが。
プリコンパイルシェーダ
今まではどう頑張ってもシェーダははランタイム上でコンパイルされ、使用されてきましたが、Metalはあらかじめプリコンパイルされ、バイトコードより実行されるため高速な動作を実現します。
まとめ
いかがだったでしょうか、巷ではVulkanが騒がれていますが、思想はほぼ同じです。
基本的にはMetalをうまく活用できれば高速なレンダリングを行うことができるよ!というのがなんだかんだいってのまとめです。
vulkanも登場し、Androidも対応機種が徐々に増えていくこのごろ、この辺の技術を理解することはかなり重要ではないでしょうか。
Metalは空いている時間を使って今後も書いていきたいと思います。