はじめに
ゲーム開発業界の大きな変化を感じています。
具体的にはゲーム開発の民主化と職種の拡大があります。
UnityのPRページ に書いてあることですが、今後 Unity はゲーム開発の領域を広げて産業界へと進出する計画があり、数年後にそれを実現する勢いがあると個人的に見ています。
Unity は、ゲームを超えて拡大し、建築、自動車、建設、エンジニアリング、映画、およびゲームなどの他の業界に侵入し、リアルタイム3D革命(RT3D)に拍車をかけています。
またUnity外の機関もそう見ている模様
Unity は、今後2年間で35%以上の最も高い成長率が予想される1つであり、最も需要のある技術スキルの1つです。
- Burning Glass, job market analytics platform
Unity に詳しくなって、イメージを形にできることを広めていきたいと考える今日この頃です。
前の投稿では Unity の Entity Component System, C# Job Systems, Burst Compile の使い方を具体的に示しました。
また最近になってコンピュータの構成と設計 第5版 上/下を読み直し(前に読んだ時は第3版)今後の Unity でのゲーム開発の要点を掴んだので、この感覚が薄れる前に記録します。
普段触れているものから掘り下げる
Unity でゲームを作っていると「どうして?」と疑問に思うこと。
- どうしてデータ指向設計をするとパフォーマンスが上がるの?
- どうしてマルチプロセッサのために並列プログラミングしなきゃいけないの?
どれもプログラムだけを眺めていては答えにたどり着けない疑問です。
今触れているゲームプログラミングの領域から、知識を掘り下げて個人的に納得できる領域まで見てみたいと思います。
C# で書いたテキストは何に変わる?
C# はコンパイラによって .dll や .exe のバイナリ形式のファイルに変換される。
.dll や .exe の中身は中間言語で書かれており、実行時にさらにマシン語に変換されて実行される
中間言語を使うメリット
- コンパイルが高速に行える
- ゲームのような修正ばかりする開発現場ではイテレーションがよく回る
- 機種依存性が低い
- 実行時にデバイス特有の言語にコンパイルされるので、機種ごとにビルドする手間が省ける
中間言語から作られるマシン語とは?
コンピュータは数字を渡すと数字を返すように作られている
マシン語とは、コンピュータに直接渡す数字の羅列のこと
どういう数字を渡すと、どういう数字が返ってくるかという決まりごとは命令セットと呼ばれ
低電力や並列処理など、需要にマッチした命令セットが私たちの周囲のデバイスに採用されている
コンピュータは何でできている?
膨大な数のトランジスタを繋ぎ合わせればコンピュータは2進数の数値演算を行うことが可能です。
トランジスタという電流の増幅装置を使って電子回路を組めば、AND, OR, NOT などの論理演算が行えます。
状態が 1 と 0 (電圧がある・ない)の操作ですので、2進数の足し算を行う回路が作れます。
面白いことに、足し算は引き算にもなります。
1 - 1 = 0 は
0001 + 1111= 0000
といった具合です。
掛け算は足し算の繰り返し
割り算は条件判定を追加できれば足し算と引き算と掛け算を組み合わせて行うことができます。
トランジスタとは?
自然界にて岩石に含まれているケイ素
ケイ素にホウ素やアルミニウムを含ませると、正の電荷が移動する導電物質に変わる(P型半導体)
ケイ素にヒ素やリンを含ませると、負の電荷が移動する導電物質に変わる(N型半導体)
これを正負正、負正負と並べ、それぞれの素材に電極を刺し、三本足の回路素子を作る
二本の電極に大きな電流を流し、残りの一本に小さな電流を流すと、まるで、水道の蛇口のように小さな電流で大きな電流を制御できる
人類がトランジスタを発明したのは1948年とされている
トランジスタの作り方
高熱の炉で岩石を溶かしてケイ素の単結晶体(インゴット)を作成(ウィンナーみたいな形)
これをダイヤモンドブレードで薄切りしてウエハを作成(薄い円盤)
鏡面になるまで磨いて、表面を酸化させて、その上に感光剤を塗る
回路設計図の通りにレーザー光をレンズを通してウエハに印刷(印刷機はステッパと呼ばれる)
感光剤が光に反応して削られるので、現像液に漬けて酸化膜を設計図通りに除去
ここでホウ素、ヒ素、リンなどを露出した部分に染み込ませて各種半導体を作成
その上に導線となるポリシリコンを重ね塗りし、設計図通りに導線が形成されるように同じように加工する
立体的に何層にもわたって塗布、印刷、除去を繰り返して集積回路が形成される
歴史的に回路の幅を狭めることで集積率を上げてきた(今日の小型化、低電力化)
インテルの第9世代CPUだと回路幅は 14nm となっている
回路の幅 10 nm は物理的な限界?
光の波長は短いものを選んでも 250 nm なので、光を使って回路を印刷するにしても、物理的限界があることがわかる
印刷方法を工夫して波長よりもずっと短い幅の回路を描いてきたことが各社(ニコンやキャノンなど)の解説資料から確認できる
光よりもずっと精細に印刷できる電子ビームを使うものも登場
しかし、印刷技術とは別で、普段私たちが感じることのできない原子レベルの現象によって、導線がくっついてしまうなど、物理的にこれ以上の集積化ができない段階にまで来ている(10nm 回路は作れてもすぐに回路が壊れる、つまり寿命が非常に短い可能性もある)
ハードウェア特性によるメモリの階層化
トランジスタを使った演算回路について掘り下げてみましたが、コンピュータに計算結果を一時的、または永続的に保存する記憶媒体(メモリ)を付けないと私たち人間は結果を観測できません(人間側からの入力もコンピュータに渡せません)
つまり Input / Output (I/O) です。
ここで演算を行う回路の計算スピードに比べると、メモリの読み書きスピードは非常に低速であるため、演算回路(CPU)はずっと待ち続けることになります。
もったいないため、高速に読み書きできるメモリを作りますが、高価&微細化が難しいため、大容量のものは一般販売できません。
そこで、CPUに近い場所に大型・高価で高速、小容量なメモリ(キャッシュ)を配置し、計算はこのキャッシュの値を読み書きして行い、一貫性が崩れないように主記憶媒体に書き戻す構成とシステムを構築しました。これを記憶階層と呼びます。
インテルのCPUはこの階層を3層まで持っていて、近い順に L1 キャッシュ、L2 キャッシュ、L3 キャッシュと呼んでいます。
CPUから離れるに従い、だんだんと低速・大容量・安価になって、最後に主記憶装置に一貫性を持って書き込まれます。
for 文を回すときは未来予測によって事前にキャッシュにデータを読み込ませるようにする仕組みも作られているため
計算で使うデータがメモリに連続的に配置されていると、非常に効率よく計算が行えます。(CPUの待ち時間を減らせる)
クロック周波数の頭打ちとマルチプロセス化
計算速度を向上させるために、回路の同期した電圧の切り替え頻度(クロック周波数)を順当に上げていった結果、発熱により、ある一定の速度以上、どんなに電力を上げても高速化しないことが判明しました。
この結果を受けて、並列に計算を行って総計算量を増やすマルチプロセッサ化するようになりました。(現在進行形)
ハードウェアの物理的限界がソフトウェアの未来を決める
記憶階層は、演算で利用する情報をキャッシュに連続的に配置すれば、CPUが待つ時間を減らすことができます。
クロック周波数をこれ以上上げる方法が見つからないため、CPUはマルチプロセッサ化を続けます。
2, 4, 8, 16スレッド(現在), 32, 64, 128, ...
(未来のことなので、断言はできませんが)
Unity ゲーム開発者はどうすれば良いのか
コンピュータの性能を最大限引き出すために
具体的には、キャッシュミスを減らすようにメモリ配置を意識し、可能な限り計算を並列化していかなければならない
Entity Component System, C# Job Systems, Burst Compile は強力な武器
ほんの数十行の書式を学ぶだけで、コンピュータの性能を最大限引き出す計算が可能になる Unity
今日のゲームは芸術と科学技術の結晶であり、その制作を支援するツールはゲーム以外の情報処理の道具として有用です。
まとめ
Unity の今後のビジョンの推察と個人的に Unity について学びたい、広めたいという意思を示し
プログラミング時の疑問をハードウェア寄りに掘り下げていき、物理的な限界からコンピュータの将来とそれに合うソフトウェアの未来像を想像してみました。
Unity の Entity Component System, C# Job Systems, Burst Compile はコンピュータの記憶階層と今後のマルチプロセッサ化時代を生き抜く強力な武器になると理解しました。(C++でシステムを作る技量は私にはありませんので…)
今後 Unity 技術者が活躍できる職場が増えるといいな(ゲームに限らず)
以上です、ここまで読んでくださりありがとうございました!